@@ -344,12 +344,20 @@ 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 multibind (
357+ self , interface : type , to : Any , scope : Union ['ScopeDecorator' , Type ['Scope' ], None ]
358+ ) -> None :
359+ raise NotImplementedError
360+
353361 def append (self , provider : Provider [T ], scope : Type ['Scope' ]) -> None :
354362 # HACK: generate a pseudo-type for this element in the list.
355363 # This is needed for scopes to work properly. Some, like the Singleton scope,
@@ -372,6 +380,21 @@ class MultiBindProvider(MultiBinder[List[T]]):
372380 """Used by :meth:`Binder.multibind` to flatten results of providers that
373381 return sequences."""
374382
383+ def multibind (
384+ self , interface : type , to : Any , scope : Union ['ScopeDecorator' , Type ['Scope' ], None ]
385+ ) -> None :
386+ try :
387+ element_type = get_args (_punch_through_alias (interface ))[0 ]
388+ except IndexError :
389+ raise InvalidInterface (f"Use typing.List[T] or list[T] to specify the element type of the list" )
390+ if isinstance (to , list ):
391+ for element in to :
392+ element_binding = self ._binder .create_binding (element_type , element , scope )
393+ self .append (element_binding .provider , element_binding .scope )
394+ else :
395+ element_binding = self ._binder .create_binding (interface , to , scope )
396+ self .append (element_binding .provider , element_binding .scope )
397+
375398 def get (self , injector : 'Injector' ) -> List [T ]:
376399 result : List [T ] = []
377400 for provider in self .get_scoped_providers (injector ):
@@ -383,6 +406,23 @@ def get(self, injector: 'Injector') -> List[T]:
383406class MapBindProvider (MultiBinder [Dict [str , T ]]):
384407 """A provider for map bindings."""
385408
409+ def multibind (
410+ self , interface : type , to : Any , scope : Union ['ScopeDecorator' , Type ['Scope' ], None ]
411+ ) -> None :
412+ try :
413+ value_type = get_args (_punch_through_alias (interface ))[1 ]
414+ except IndexError :
415+ raise InvalidInterface (
416+ f"Use typing.Dict[K, V] or dict[K, V] to specify the value type of the dict"
417+ )
418+ if isinstance (to , dict ):
419+ for key , value in to .items ():
420+ element_binding = self ._binder .create_binding (value_type , value , scope )
421+ self .append (KeyValueProvider (key , element_binding .provider ), element_binding .scope )
422+ else :
423+ element_binding = self ._binder .create_binding (interface , to , scope )
424+ self .append (element_binding .provider , element_binding .scope )
425+
386426 def get (self , injector : 'Injector' ) -> Dict [str , T ]:
387427 map : Dict [str , T ] = {}
388428 for provider in self .get_scoped_providers (injector ):
@@ -549,29 +589,7 @@ def multibind(
549589 :param scope: Optional Scope in which to bind.
550590 """
551591 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 )
592+ multi_binder .multibind (interface , to , scope )
575593
576594 def _get_multi_binder (self , interface : type ) -> MultiBinder :
577595 multi_binder : MultiBinder
0 commit comments