punq icon indicating copy to clipboard operation
punq copied to clipboard

How To resolve class dependencies registered by key

Open jbcpollak opened this issue 5 years ago • 3 comments

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?

jbcpollak avatar Apr 15 '20 15:04 jbcpollak

This also sounds like a sensible feature. I'll take a look at this one, too :)

bobthemighty avatar Jun 05 '20 07:06 bobthemighty

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.

strmwalker avatar Aug 10 '21 14:08 strmwalker

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()

strmwalker avatar Aug 11 '21 08:08 strmwalker