mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-29 04:53:59 +03:00
Update the declarative container docs
This commit is contained in:
parent
925801c73f
commit
e479e2cb94
|
@ -3,53 +3,42 @@ Declarative containers
|
||||||
|
|
||||||
.. currentmodule:: dependency_injector.containers
|
.. currentmodule:: dependency_injector.containers
|
||||||
|
|
||||||
:py:class:`DeclarativeContainer` is inversion of control container that
|
:py:class:`DeclarativeContainer` is a collection of the providers defined in the declarative
|
||||||
could be defined in declarative manner. It should cover most of the cases
|
manner. It covers the use cases when your application structure does not change in the runtime.
|
||||||
when list of providers that would be included in container is deterministic
|
|
||||||
(container will not change its structure in runtime).
|
|
||||||
|
|
||||||
Declarative containers have to extend base declarative container class -
|
Container has the ``.providers`` attribute. It is a dictionary of the container providers.
|
||||||
:py:class:`dependency_injector.containers.DeclarativeContainer`.
|
|
||||||
|
|
||||||
Declarative container's providers have to be defined like container's class
|
|
||||||
attributes. Every provider in container has name. This name should follow
|
|
||||||
``some_provider`` convention, that is standard naming convention for
|
|
||||||
attribute names in Python.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Declarative containers have several features that could be useful
|
|
||||||
for some kind of operations on container's providers, please visit API
|
|
||||||
documentation for getting full list of features -
|
|
||||||
:py:class:`dependency_injector.containers.DeclarativeContainer`.
|
|
||||||
|
|
||||||
Here is an simple example of defining declarative container with several
|
|
||||||
factories:
|
|
||||||
|
|
||||||
.. image:: /images/containers/declarative.png
|
|
||||||
:width: 85%
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/containers/declarative.py
|
.. literalinclude:: ../../examples/containers/declarative.py
|
||||||
:language: python
|
:language: python
|
||||||
|
:lines: 3-
|
||||||
|
|
||||||
Example of declarative containers inheritance:
|
Your declarative container has to extend base declarative container class -
|
||||||
|
:py:class:`dependency_injector.containers.DeclarativeContainer`.
|
||||||
|
|
||||||
.. image:: /images/containers/declarative_inheritance.png
|
Declarative container classes can not have any methods or any other attributes then providers.
|
||||||
:width: 100%
|
|
||||||
:align: center
|
The declarative container providers should only be used after the container is initialized.
|
||||||
|
|
||||||
|
The container class provides next attributes:
|
||||||
|
|
||||||
|
- ``providers`` - the dictionary of all the container providers
|
||||||
|
- ``cls_providers`` - the dictionary of the container providers of the current container
|
||||||
|
- ``inherited_providers`` - the dictionary of all the inherited container providers
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/containers/declarative_inheritance.py
|
.. literalinclude:: ../../examples/containers/declarative_inheritance.py
|
||||||
:language: python
|
:language: python
|
||||||
|
:lines: 3-
|
||||||
|
|
||||||
Example of declarative containers's provider injections:
|
Injections in the declarative container are done the usual way:
|
||||||
|
|
||||||
.. image:: /images/containers/declarative_injections.png
|
|
||||||
:width: 100%
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/containers/declarative_injections.py
|
.. literalinclude:: ../../examples/containers/declarative_injections.py
|
||||||
:language: python
|
:language: python
|
||||||
|
:lines: 3-
|
||||||
|
|
||||||
|
You can override the container providers when you create the container instance:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/containers/declarative_override_providers.py
|
||||||
|
:language: python
|
||||||
|
:lines: 3-
|
||||||
|
|
||||||
.. disqus::
|
.. disqus::
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
IoC Containers
|
Containers
|
||||||
==============
|
==========
|
||||||
|
|
||||||
Containers are collections of providers. Main purpose of containers is to group
|
Containers are collections of the providers.
|
||||||
providers.
|
|
||||||
|
|
||||||
There are, actually, several popular cases of containers usage:
|
There are several use cases how you can use containers:
|
||||||
|
|
||||||
+ Keeping all providers in a single container.
|
+ Keeping all the providers in a single container (most common).
|
||||||
+ Grouping of providers from the same architectural layer (for example,
|
+ Grouping of the providers from the same architectural layer (for example,
|
||||||
``Services``, ``Models`` and ``Forms`` containers).
|
``Services``, ``Models`` and ``Forms`` containers).
|
||||||
+ Grouping of providers from the same functional groups (for example,
|
+ Grouping of providers from the same functional groups (for example,
|
||||||
container ``Users``, that contains all functional parts of ``Users``
|
container ``Users``, that contains all functional parts of the ``users``
|
||||||
component).
|
package).
|
||||||
|
|
||||||
Also, for both of these and some other cases, it might be useful to attach
|
|
||||||
some init / shutdown functionality or something else, that deals with group
|
|
||||||
of providers.
|
|
||||||
|
|
||||||
Containers package API docs - :py:mod:`dependency_injector.containers`.
|
Containers package API docs - :py:mod:`dependency_injector.containers`.
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 23 KiB |
Binary file not shown.
Before Width: | Height: | Size: 64 KiB |
Binary file not shown.
Before Width: | Height: | Size: 112 KiB |
|
@ -1,23 +1,22 @@
|
||||||
"""Declarative IoC container simple example."""
|
"""Declarative container example."""
|
||||||
|
|
||||||
import dependency_injector.containers as containers
|
from dependency_injector import containers, providers
|
||||||
import dependency_injector.providers as providers
|
|
||||||
|
|
||||||
|
|
||||||
# Defining declarative IoC container:
|
|
||||||
class Container(containers.DeclarativeContainer):
|
class Container(containers.DeclarativeContainer):
|
||||||
"""Example IoC container."""
|
|
||||||
|
|
||||||
factory1 = providers.Factory(object)
|
factory1 = providers.Factory(object)
|
||||||
|
|
||||||
factory2 = providers.Factory(object)
|
factory2 = providers.Factory(object)
|
||||||
|
|
||||||
|
|
||||||
# Creating some objects:
|
container = Container()
|
||||||
object1 = Container.factory1()
|
|
||||||
object2 = Container.factory2()
|
|
||||||
|
|
||||||
# Making some asserts:
|
object1 = container.factory1()
|
||||||
assert object1 is not object2
|
object2 = container.factory2()
|
||||||
assert isinstance(object1, object)
|
|
||||||
assert isinstance(object2, object)
|
print(container.providers)
|
||||||
|
# {
|
||||||
|
# 'factory1': <dependency_injector.providers.Factory(...),
|
||||||
|
# 'factory2': <dependency_injector.providers.Factory(...),
|
||||||
|
# }
|
||||||
|
|
|
@ -1,30 +1,34 @@
|
||||||
"""Declarative IoC containers inheritance example."""
|
"""Declarative containers inheritance example."""
|
||||||
|
|
||||||
import dependency_injector.containers as containers
|
from dependency_injector import containers, providers
|
||||||
import dependency_injector.providers as providers
|
|
||||||
|
|
||||||
|
|
||||||
class ContainerA(containers.DeclarativeContainer):
|
class ContainerA(containers.DeclarativeContainer):
|
||||||
"""Example IoC container A."""
|
|
||||||
|
|
||||||
provider1 = providers.Factory(object)
|
provider1 = providers.Factory(object)
|
||||||
|
|
||||||
|
|
||||||
class ContainerB(ContainerA):
|
class ContainerB(ContainerA):
|
||||||
"""Example IoC container B."""
|
|
||||||
|
|
||||||
provider2 = providers.Singleton(object)
|
provider2 = providers.Singleton(object)
|
||||||
|
|
||||||
|
|
||||||
# Making some asserts for `providers` attribute:
|
assert ContainerA.providers == {
|
||||||
assert ContainerA.providers == dict(provider1=ContainerA.provider1)
|
'provider1': ContainerA.provider1,
|
||||||
assert ContainerB.providers == dict(provider1=ContainerA.provider1,
|
}
|
||||||
provider2=ContainerB.provider2)
|
assert ContainerB.providers == {
|
||||||
|
'provider1': ContainerA.provider1,
|
||||||
|
'provider2': ContainerB.provider2,
|
||||||
|
}
|
||||||
|
|
||||||
# Making some asserts for `cls_providers` attribute:
|
assert ContainerA.cls_providers == {
|
||||||
assert ContainerA.cls_providers == dict(provider1=ContainerA.provider1)
|
'provider1': ContainerA.provider1,
|
||||||
assert ContainerB.cls_providers == dict(provider2=ContainerB.provider2)
|
}
|
||||||
|
assert ContainerB.cls_providers == {
|
||||||
|
'provider2': ContainerB.provider2,
|
||||||
|
}
|
||||||
|
|
||||||
# Making some asserts for `inherited_providers` attribute:
|
assert ContainerA.inherited_providers == {}
|
||||||
assert ContainerA.inherited_providers == dict()
|
assert ContainerB.inherited_providers == {
|
||||||
assert ContainerB.inherited_providers == dict(provider1=ContainerB.provider1)
|
'provider1': ContainerA.provider1,
|
||||||
|
}
|
||||||
|
|
|
@ -1,35 +1,41 @@
|
||||||
"""Declarative IoC container's provider injections example."""
|
"""Declarative container injections example."""
|
||||||
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import collections
|
|
||||||
|
|
||||||
import dependency_injector.containers as containers
|
from dependency_injector import containers, providers
|
||||||
import dependency_injector.providers as providers
|
|
||||||
|
|
||||||
|
|
||||||
UsersService = collections.namedtuple('UsersService', ['db'])
|
class UserService:
|
||||||
AuthService = collections.namedtuple('AuthService', ['db', 'users_service'])
|
def __init__(self, db: sqlite3.Connection):
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
|
||||||
class Services(containers.DeclarativeContainer):
|
class AuthService:
|
||||||
"""IoC container of service providers."""
|
def __init__(self, db: sqlite3.Connection, user_service: UserService):
|
||||||
|
self.db = db
|
||||||
|
self.user_service = user_service
|
||||||
|
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
database = providers.Singleton(sqlite3.connect, ':memory:')
|
database = providers.Singleton(sqlite3.connect, ':memory:')
|
||||||
|
|
||||||
users = providers.Factory(UsersService,
|
user_service = providers.Factory(
|
||||||
db=database)
|
UserService,
|
||||||
|
db=database,
|
||||||
|
)
|
||||||
|
|
||||||
auth = providers.Factory(AuthService,
|
auth_service = providers.Factory(
|
||||||
db=database,
|
AuthService,
|
||||||
users_service=users)
|
db=database,
|
||||||
|
user_service=user_service,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Retrieving service providers from container:
|
container = Container()
|
||||||
users_service = Services.users()
|
|
||||||
auth_service = Services.auth()
|
|
||||||
|
|
||||||
# Making some asserts:
|
user_service = container.user_service()
|
||||||
assert users_service.db is auth_service.db is Services.database()
|
auth_service = container.auth_service()
|
||||||
assert isinstance(auth_service.users_service, UsersService)
|
|
||||||
assert users_service is not Services.users()
|
assert user_service.db is auth_service.db is container.database()
|
||||||
assert auth_service is not Services.auth()
|
assert isinstance(auth_service.user_service, UserService)
|
||||||
|
|
17
examples/containers/declarative_override_providers.py
Normal file
17
examples/containers/declarative_override_providers.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
"""Declarative container provider override example."""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
database = providers.Singleton(sqlite3.connect, ':memory:')
|
||||||
|
|
||||||
|
|
||||||
|
container = Container(database=mock.Mock(sqlite3.Connection))
|
||||||
|
|
||||||
|
database = container.database()
|
||||||
|
assert isinstance(database, mock.Mock)
|
Loading…
Reference in New Issue
Block a user