-
Notifications
You must be signed in to change notification settings - Fork 94
Description
I've used Guice in the past for registering and instantiating plug-ins using the multibind extension. I found that straight-forward to do based on the Guice documentation. However, I'm struggling to do the same using python injector. All the tests and documentation I've found use multibind
in conjunction with lists or dictionaries containing concrete values (strings or ints). I need the plug-ins to be instantiated by the DI framework.
If I bind to a list of classes like this
binder.multibind(List[Plugin], [GreenPlugin, RedPlugin])
then injector.get(List[Plugin])
just returns the list of classes, rather than a list of instantiated objects.
If I do this:
binder.multibind(List[Plugin], GreenPlugin)
binder.multibind(List[Plugin], RedPlugin)
then I get the following error when calling injector.get(List[Plugin])
> return [i for provider in self._providers for i in provider.get(injector)]
E TypeError: 'GreenPlugin' object is not iterable
I've been able to get this approach to work by having my base Plugin class pretend to be iterable like so:
class Plugin:
# Dependency Injection hack for making multibind work
def __getitem__(self, item):
if item == 0:
return self
raise IndexError
but it's not very nice.
I could do this:
def configure(binder):
binder.bind(GreenPlugin)
binder.bind(RedPlugin)
@provider
def get_plugins(green: GreenPlugin, red: RedPlugin) -> List[Plugin]:
return [green, red]
but that results in a lot of repetition. Adding a new plugin would mean binding it, adding it to the argument list of the provider function and the list it returns.
I feel like I must be missing something. How should a plug-in system be implemented using python injector?