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.