Open warvariuc opened 1 month ago
@warvariuc Thanks for the question!
Can you give an example of cases where this would be useful? I have never yet encountered this functionality in my experience with dependency_injector
UPD: I found a description of this functionality here. I couldn’t immediately understand in what situations this would be useful, because we have already implemented redefinition of one or multiple providers. I'm waiting for your examples
Here is an example how we use this in our code.
class Adapters(dependency_injector.containers.DeclarativeContainer.DeclarativeContainer):
"""A set of dependencies replaced as a whole in tests."""
email_client: dependency_injector.providers.Provider[EmailClient] = dependency_injector.providers.Singleton(EmailHttpClient, ...)
...
class ApplicationContainer(dependency_injector.containers.DeclarativeContainer):
"""Dependencies used in our code."""
adapters: Adapters = dependency_injector.providers .DependenciesContainer() # type: ignore
...
email_client: dependency_injector.providers.Provider[EmailClient] = adapters.email_client
...
And in tests we override some dependencies:
class TestAdapters(Adapters):
__test__ = False
email_client: dip.Singleton[EmailClient] = dip.Singleton(TestEmailClient)
...
@pytest.fixture()
def inject_test_deps() -> containers.ApplicationContainer:
with containers.container.adapters.override(TestAdapters()):
yield containers.container
@warvariuc thanks for example. I think this can be useful in a code base where DI containers are used everywhere and there are several of them. I'll probably implement what you suggested after I finish the documentation
Maybe there is a simpler/easier to override many providers at once. I am not sure. In the version I posted it's good that you declare test dependencies in a class, instead of of overriding them imperatively one by one.
Maybe there is a simpler/easier to override many providers at once. I am not sure. In the version I posted it's good that you declare test dependencies in a class, instead of of overriding them imperatively one by one.
If I understand you correctly, it is already possible to override many providers: https://injection.readthedocs.io/latest/testing/provider-overriding.html#override-multiple-providers
But above it seems you are proposing, so to speak, the “next level” of overriding - this is not the level of overriding providers, but containers. Although this can certainly be replaced completely by overriding providers
If batch override of providers using the override_providers(**providers)
method is enough for you, then I think you can close the current issue. If you want to override containers, I'm ready to try to implement it
The docs say:
This allows overriding providers.
But what about overriding a container?
https://github.com/ets-labs/python-dependency-injector/blob/cc2304e46e054ae08dc12995428759fbfb51af10/src/dependency_injector/containers.pyx#L220