Constructor arg order causes dependencies to be recreated
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.
Thank you for the report!
It's a bug and it should be fixed.
I would try to take care of it.
Solution proposal:
- Do not use nested caches to store resolved objects for references. Use global UUID keys to store everything in the same heap.
- Speed up resolver algorithm by pre-calculating full chain of objects resolution so resolver and state would become a
forloop. - Do not build
**kwargsfor every dependency. Pass state directly to the factory so factory could take all necessary attributes itself.