What's the point of this library? #402
Replies: 1 comment 6 replies
-
Hello Stefano, Imagine a large dependency injection-based application. You have a service that uses a client, that uses a database, that requires a configuration object: def controller1():
service = Service(
client=Client(
database=Database(
config=Config(
value1=1,
value2=2,
),
),
),
)
...
def controller2():
service = Service(
client=Client(
database=Database(
config=Config(
value1=1,
value2=2,
),
),
),
)
...
def controller3():
service = Service(
client=Client(
database=Database(
config=Config(
value1=1,
value2=2,
),
),
),
)
... Now we need to change database type. We will use def controller1():
service = Service(
client=Client(
database=ExtendedDatabase( # <-- Change 1
config=Config(
value1=1,
value2=2,
),
),
),
)
...
def controller2():
service = Service(
client=Client(
database=ExtendedDatabase( # <-- Change 2
config=Config(
value1=1,
value2=2,
),
),
),
)
...
def controller3():
service = Service(
client=Client(
database=ExtendedDatabase( # <-- Change 3
config=Config(
value1=1,
value2=2,
),
),
),
)
... Why that happens? Cause you had to duplicate too much knowledge about how you assemble objects. Dependency Injector provides you with building block so you could describe how you're going to assemble your objects without actually assembling them. class Container(containers.DeclarativeContainer):
config = providers.Factory(Config, value1=1, value2=2)
database = providers.Factory(ExtendedDatabase, config=config) # <-- The only change
client = providers.Factory(Client, database=database)
service = providers.Factory(Service, client=client)
def controller1(container: Container):
service = container.service()
...
def controller2(container: Container):
service = container.service()
...
def controller3(container: Container):
service = container.service()
... The benefit you're talking about could be a downside on a lager scale. The good news is that with the Dependency Injector you still see what is passed where in the container: class Container(containers.DeclarativeContainer):
config = providers.Factory(Config, value1=1, value2=2)
database = providers.Factory(ExtendedDatabase, config=config)
client = providers.Factory(Client, database=database)
service = providers.Factory(Service, client=client) |
Beta Was this translation helpful? Give feedback.
-
I don't get the core reason behind this library. All it does is to save you to pass the dependency at invocation time, something that not only is literally a few keystrokes, but it actually removes the caller from the benefit to notice that the dependency has been passed, so it's actually detrimental to readability, as the dependency is passed magically without any clear indication that a dependency has been passed and is going to be used unless you specifically look inside the code of the callee.
Finally, how does this affect debuggability?
Beta Was this translation helpful? Give feedback.
All reactions