@@ -344,12 +344,18 @@ def __repr__(self) -> str:
344344class MultiBinder (Provider , Generic [T ]):
345345 """Provide a list of instances via other Providers."""
346346
347+ __metaclass__ = ABCMeta
348+
347349 _multi_bindings : List ['Binding' ]
348350
349351 def __init__ (self , parent : 'Binder' ) -> None :
350352 self ._multi_bindings = []
351353 self ._binder = Binder (parent .injector , auto_bind = False , parent = parent )
352354
355+ @abstractmethod
356+ def multbind (self , interface : type , to : Any , scope : Union ['ScopeDecorator' , Type ['Scope' ], None ]) -> None :
357+ raise NotImplementedError
358+
353359 def append (self , provider : Provider [T ], scope : Type ['Scope' ]) -> None :
354360 # HACK: generate a pseudo-type for this element in the list.
355361 # This is needed for scopes to work properly. Some, like the Singleton scope,
@@ -372,6 +378,21 @@ class MultiBindProvider(MultiBinder[List[T]]):
372378 """Used by :meth:`Binder.multibind` to flatten results of providers that
373379 return sequences."""
374380
381+ def multibind (
382+ self , interface : type , to : Any , scope : Union ['ScopeDecorator' , Type ['Scope' ], None ]
383+ ) -> None :
384+ try :
385+ element_type = get_args (_punch_through_alias (interface ))[0 ]
386+ except IndexError :
387+ raise InvalidInterface (f"Use typing.List[T] or list[T] to specify the element type of the list" )
388+ if isinstance (to , list ):
389+ for element in to :
390+ element_binding = self ._binder .create_binding (element_type , element , scope )
391+ self .append (element_binding .provider , element_binding .scope )
392+ else :
393+ element_binding = self ._binder .create_binding (interface , to , scope )
394+ self .append (element_binding .provider , element_binding .scope )
395+
375396 def get (self , injector : 'Injector' ) -> List [T ]:
376397 result : List [T ] = []
377398 for provider in self .get_scoped_providers (injector ):
@@ -383,6 +404,23 @@ def get(self, injector: 'Injector') -> List[T]:
383404class MapBindProvider (MultiBinder [Dict [str , T ]]):
384405 """A provider for map bindings."""
385406
407+ def multibind (
408+ self , interface : type , to : Any , scope : Union ['ScopeDecorator' , Type ['Scope' ], None ]
409+ ) -> None :
410+ try :
411+ value_type = get_args (_punch_through_alias (interface ))[1 ]
412+ except IndexError :
413+ raise InvalidInterface (
414+ f"Use typing.Dict[K, V] or dict[K, V] to specify the value type of the dict"
415+ )
416+ if isinstance (to , dict ):
417+ for key , value in to .items ():
418+ element_binding = self ._binder .create_binding (value_type , value , scope )
419+ self .append (KeyValueProvider (key , element_binding .provider ), element_binding .scope )
420+ else :
421+ element_binding = self ._binder .create_binding (interface , to , scope )
422+ self .append (element_binding .provider , element_binding .scope )
423+
386424 def get (self , injector : 'Injector' ) -> Dict [str , T ]:
387425 map : Dict [str , T ] = {}
388426 for provider in self .get_scoped_providers (injector ):
@@ -549,29 +587,7 @@ def multibind(
549587 :param scope: Optional Scope in which to bind.
550588 """
551589 multi_binder = self ._get_multi_binder (interface )
552- if isinstance (multi_binder , MultiBindProvider ) and isinstance (to , list ):
553- try :
554- element_type = get_args (_punch_through_alias (interface ))[0 ]
555- except IndexError :
556- raise InvalidInterface (
557- f"Use typing.List[T] or list[T] to specify the element type of the list"
558- )
559- for element in to :
560- element_binding = self .create_binding (element_type , element , scope )
561- multi_binder .append (element_binding .provider , element_binding .scope )
562- elif isinstance (multi_binder , MapBindProvider ) and isinstance (to , dict ):
563- try :
564- value_type = get_args (_punch_through_alias (interface ))[1 ]
565- except IndexError :
566- raise InvalidInterface (
567- f"Use typing.Dict[K, V] or dict[K, V] to specify the value type of the dict"
568- )
569- for key , value in to .items ():
570- element_binding = self .create_binding (value_type , value , scope )
571- multi_binder .append (KeyValueProvider (key , element_binding .provider ), element_binding .scope )
572- else :
573- element_binding = self .create_binding (interface , to , scope )
574- multi_binder .append (element_binding .provider , element_binding .scope )
590+ multi_binder .multibind (interface , to , scope )
575591
576592 def _get_multi_binder (self , interface : type ) -> MultiBinder :
577593 multi_binder : MultiBinder
0 commit comments