injector
injector copied to clipboard
use specific Injector instance as `inject` decorator
This has been in my mind for some time so I decided to finally write it.
Would that be possible to specify the Injector instance that should be used to inject dependencies? I see it the following way
container = Injector([module])
...
@container.inject # or maybe @inject(container)
def do_something(a: Dependency):
...
My motivation is that I have multiple python modules, each one configuring it's own dependencies so each module (in general) expects different instances of dependencies.
I know that the proposed solution requires a variable container to be defined at interpretation time but not always is that undesireable. What do you think?
My workaround currently is calling container.get but I don't really like it.
Or is there something I don't understand about how injector works and inject chooses "the most local" container?
I'm not entirely sure I get your use case, but I think the one of the closest thing we have is creating new types with NewType and binding different NewTypes to different instances. I've used that successfully. If the modules don't interact with each other, having parent/child injectors is another way of partially sharing injector configuration. Would any of those work for you?
NewType for sure will work but it introduces boilerplate, even though minimal, so it's not optimal.
To demonstrate my use case:
# common.container
class Container(injector.Module):
def configure(self, binder):
binder.bind(MessageBus, to=MessageBus)
# module_a.container
class Container(injector.Module):
def configure(self, binder):
binder.bind(SomeCommonBase, to=module_a.Concrete)
container = injector.Injector([Container(), common.container.Container()])
# module_b.container
class Container(injector.Module):
def configure(self, binder):
binder.bind(SomeCommonBase, to=module_b.Concrete)
container = injector.Injector([Container(), common.container.Container()])
# common.message_bus
class MessageBus:
@injector.inject
def __init__(self, module_specific_instance: SomeCommonBase):
...
Hey @r2rstep, I'm also not entirely surely I understand this.
In the code sample you included above, where would the "pick the Injector instance" logic go?
I feel like this misses some context and possibly a clarification of what problem is being solved here. In general I'd not expect a piece a single application context to define or use multiple Injector instances.
After re-reading I think I understand it better now. I believe if you want to dispatch to multiple Injector instances you may need to do it manually for the time being (get access to the instance, call get() on it).
I'd maybe try to put all of that in a single Injector instance so your various modules could coexist there but I understand it may not be feasible.
yeah, it's more like a feature request :) The case is for modular monolith where each module should define own dependencies.
Anyway, thanks for taking time to respond :)