punq
punq copied to clipboard
How To resolve class dependencies registered by key
lets say I have something like this:
class Dependency:
pass
class ConsumerOfA:
def __init__(self, dep: Dependency):
self.dep = dep
container.register('depA', Dependency('a'))
container.register('depB', Dependency('b'))
container.register(ConsumerOfA)
cOA = container.resolve(ConsumerOfA)
How do I ensure that ConsumerOfA gets depA vs depB? Is there a way to add an annotation on init to make sure the right one is injected?
This also sounds like a sensible feature. I'll take a look at this one, too :)
This could be achieved with string annotations on __init__ args:
class Dependency:
pass
class ConsumerOfA:
def __init__(self, dep: 'depA'):
self.dep = dep
container.register('depA', Dependency('a'))
container.register('depB', Dependency('b'))
container.register(ConsumerOfA)
cOA = container.resolve(ConsumerOfA)
Drawback of this approach is that you introducing DI to your client code, and this breaks static analysis tools like mypy.
Just figured out best way to solve this problem. You can use typing.NewType to create aliases:
from punq import Container
class Dependency:
def __init__(self, value):
self.value = value
DependencyA = NewType('DependencyA', Dependency)
DependencyB = NewType('DependencyB', Dependency)
class ConsumerOfA:
def __init__(self, dep: DependencyA):
self.dep = dep
class ConsumerOfB:
def __init__(self, dep: DependencyB):
self.dep = dep
def main():
container = Container()
container.register(DependencyA, instance=Dependency('a'))
container.register(DependencyB, instance=Dependency('b'))
container.register(ConsumerOfA)
container.register(ConsumerOfB)
coa: ConsumerOfA = container.resolve(ConsumerOfA)
cob: ConsumerOfB = container.resolve(ConsumerOfB)
print(coa.dep.value)
print(cob.dep.value)
if __name__ == '__main__':
main()