.. _provider: Provider **************** **Provider** is an object whose members are used to construct dependencies. ``Provider`` contains different factories and other entities and then is used to create a ``Container``. You can have multiple providers in one application combining them in different ways to make it more modular. To configure provider you can either inherit and use decorators on your methods or just create an instance and use its methods. For example, imagine you have two classes: connection which is retrieved from external library and a dao which requires such a connection. .. code-block:: python class Connection: pass class DAO: def __init__(self, conn: Connection): pass You can configure ``Provider`` with code like this: .. code-block:: python from dishka import make_container, Provider, Scope def get_connection() -> Iterable[Connection]: conn = connect(uri) yield conn conn.close() provider = Provider(scope=Scope.APP) provider.provide(get_connection) provider.provide(DAO) container = make_container(provider) Or using inheritance: .. code-block:: python from dishka import make_container, Provider, provide, Scope class MyProvider(Provider): @provide def get_connection(self) -> Iterable[Connection]: conn = connect(uri) yield conn conn.close() dao = provide(DAO) container = make_container(MyProvider(scope=Scope.APP)) Your class-based provider can have ``__init__`` method and methods accessing ``self`` as usual. It can be useful for passing configuration: .. code-block:: python class MyProvider(Provider): def __init__(self, uri: str, scope: Scope): super().__init__(scope=scope) # do not forget `super` self.uri = uri @provide def get_connection(self) -> Iterable[Connection]: conn = connect(self.uri) # use passed configuration yield conn conn.close() dao = provide(DAO) provider = MyProvider(uri=os.getenv("DB_URI"), scope=Scope.APP) container = make_container(provider) Dependencies have scope and there are three places to set it (from highest to lowest priority): * When registering single factory passing to ``provide`` method: .. code-block:: python class MyProvider(Provider): dao = provide(DAO, scope=Scope.APP) * When instantiating provider: .. code-block:: python provider = Provider(scope=Scope.APP) * Inside class: .. code-block:: python class MyProvider(Provider): scope = Scope.APP .. raw:: html
.. warning:: Provider internally defines attributes like ``factories``, ``aliases``, ``decorators``, and ``context_vars``. Overriding them in your subclass will break dependency resolution. Use another name. .. code-block:: python class MyProvider(Provider): scope = ... factories = provide(SomeClass) # ERROR .. raw:: html
Though it is a normal object, not all attributes are analyzed by ``Container``, but only those which are marked with special functions: .. toctree:: provide provide_all alias from_context decorate