dependencies icon indicating copy to clipboard operation
dependencies copied to clipboard

Constructor arg order causes dependencies to be recreated

Open jnis23 opened this issue 3 years ago • 2 comments

Hi @proofit404,

I'm loving dependencies so far, but I'm noticing some unexpected behavior when an uninitialized dependency comes after an initialized one in the constructor args.

This works fine:

from dependencies import Injector


class A:
    pass


class B:
    pass


class C:
    def __init__(self, a):
        self.a = a


class D:
    def __init__(self, b, a):
        self.b = b
        self.a = a


class Container(Injector):
    a = A
    b = B
    c = C
    d = D


with Container as scope:
    assert scope.c.a is scope.d.a

but when I invert a and b in D's constructor, a is recreated during injection:

class D:
    def __init__(self, a, b):
        self.b = b
        self.a = a


class Container(Injector):
    a = A
    b = B
    c = C
    d = D


with Container as scope:
    assert scope.c.a is scope.d.a  # AssertionError

I would expect this to be agnostic of the argument ordering. Is there a reason for this that I'm missing? Looking at the code, I would expect this call to match to be the diff in the set instead of all args. Obviously not a huge deal to reorder the args, but took me an embarrassingly long time to track this down 😅 and would imagine this would save others from a similar issue in the future.

jnis23 avatar Sep 23 '22 18:09 jnis23

Thank you for the report!

It's a bug and it should be fixed.

I would try to take care of it.

proofit404 avatar Sep 23 '22 18:09 proofit404

Solution proposal:

  1. Do not use nested caches to store resolved objects for references. Use global UUID keys to store everything in the same heap.
  2. Speed up resolver algorithm by pre-calculating full chain of objects resolution so resolver and state would become a for loop.
  3. Do not build **kwargs for every dependency. Pass state directly to the factory so factory could take all necessary attributes itself.

proofit404 avatar Nov 04 '22 20:11 proofit404