Container copyingΒΆ
You can create declarative container copies using @containers.copy()
decorator.
import sqlite3
from unittest import mock
from dependency_injector import containers, providers
class Service:
def __init__(self, db):
self.db = db
class SourceContainer(containers.DeclarativeContainer):
database = providers.Singleton(sqlite3.connect, ":memory:")
service = providers.Factory(Service, db=database)
# Copy ``SourceContainer`` providers into ``DestinationContainer``:
@containers.copy(SourceContainer)
class DestinationContainer(SourceContainer):
database = providers.Singleton(mock.Mock)
if __name__ == "__main__":
container = DestinationContainer()
service = container.service()
assert isinstance(service.db, mock.Mock)
Decorator @containers.copy()
copies providers from source container to destination container.
Destination container provider will replace source provider, if names match.
Decorator @containers.copy()
helps you when you create derived declarative containers
from the base one. Base container often keeps default dependencies while derived containers define
overriding providers. Without @containers.copy()
decorator, overridden providers are available
in the derived container, but base class dependencies continue to be bound to the base class providers.
class Base(containers.DeclarativeContainer):
dependency = providers.Dependency(instance_of=str, default="Default value")
service = providers.Factory(Service, dependency=dependency)
@containers.copy(Base)
class Derived1(Base):
dependency = providers.Dependency(instance_of=str, default="Derived 1")
# @containers.copy(Base) # <-- No @copy decorator
class Derived2(Base):
dependency = providers.Dependency(instance_of=str, default="Derived 2")
if __name__ == "__main__":
container1 = Derived1()
service1 = container1.service()
print(service1.dependency) # Derived 1
container2 = Derived2()
service2 = container2.service()
print(service2.dependency) # Default value