Dependency provider¶
Dependency
provider is a placeholder for a dependency of a certain type.
To specify a type of the dependency use instance_of
argument: Dependency(instance_of=SomeClass)
.
Dependency provider will control that returned object is an instance of instance_of
type.
import abc
import dataclasses
from dependency_injector import containers, providers
class DbAdapter(metaclass=abc.ABCMeta):
...
class SqliteDbAdapter(DbAdapter):
...
class PostgresDbAdapter(DbAdapter):
...
@dataclasses.dataclass
class UserService:
database: DbAdapter
class Container(containers.DeclarativeContainer):
database = providers.Dependency(instance_of=DbAdapter)
user_service = providers.Factory(
UserService,
database=database,
)
if __name__ == "__main__":
container1 = Container(database=providers.Singleton(SqliteDbAdapter))
container2 = Container(database=providers.Singleton(PostgresDbAdapter))
assert isinstance(container1.user_service().database, SqliteDbAdapter)
assert isinstance(container2.user_service().database, PostgresDbAdapter)
container3 = Container(database=providers.Singleton(object))
container3.user_service() # <-- raises error:
# <object ...> is not an instance of DbAdapter
To provide a dependency you need to override the Dependency
provider. You can call
provider .override()
method or provide an overriding provider when creating a container.
See Provider overriding. If you don’t provide a dependency, Dependency
provider
will raise an error:
class Container(containers.DeclarativeContainer):
database = providers.Dependency(instance_of=DbAdapter)
user_service = providers.Factory(
UserService,
database=database,
)
if __name__ == "__main__":
container = Container()
container.user_service() # <-- raises error:
# Dependency "Container.database" is not defined
You also can provide a default for the dependency. To provide a default use default
argument:
Dependency(..., default=...)
. Default can be a value or a provider. If default is not a provider,
dependency provider will wrap it into the Object
provider.
class Container(containers.DeclarativeContainer):
cache = providers.Dependency(instance_of=Cache, default=InMemoryCache())
if __name__ == "__main__":
container = Container()
cache = container.cache() # provides InMemoryCache()
See also: Check container dependencies.