Create multiple containers page

This commit is contained in:
Roman Mogylatov 2020-09-04 23:13:08 -04:00
parent 4c5a5192b0
commit 65f599fae0
26 changed files with 257 additions and 224 deletions

View File

@ -0,0 +1,87 @@
.. _application-multiple-containers:
Application example (multiple containers)
=========================================
.. meta::
:keywords: Python,Dependency Injection,Inversion of Control,Container,Example,Application,
Framework,AWS,boto3,client
:description: This example shows how you can create an application using multiple declarative
containers. We build an example Python micro application following the dependency
injection principle. It consists from several services with a domain logic that
have dependencies on database & AWS S3.
This example shows how you can create an application using multiple declarative containers. Using
multiple declarative containers is a good choice for a large application. For
building a moderate or a small size application refer to :ref:`application-single-container`.
We build an example micro application following the dependency injection principle. It consists
of several services with a domain logic. The services have dependencies on database & AWS S3.
.. image:: images/application.png
:width: 100%
:align: center
Start from the scratch or jump to the section:
.. contents::
:local:
:backlinks: none
You can find the source code and instructions for running on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/application-multiple-containers>`_.
Application structure
---------------------
Application consists of an ``example`` package, a configuration file and a ``requirements.txt``
file.
.. code-block:: bash
./
├── example/
│ ├── __init__.py
│ ├── __main__.py
│ ├── containers.py
│ └── services.py
├── config.yml
└── requirements.txt
Containers
----------
Listing of the ``example/containers.py``:
.. literalinclude:: ../../examples/miniapps/application-multiple-containers/example/containers.py
:language: python
Main module
-----------
Listing of the ``example/__main__.py``:
.. literalinclude:: ../../examples/miniapps/application-multiple-containers/example/__main__.py
:language: python
Services
--------
Listing of the ``example/services.py``:
.. literalinclude:: ../../examples/miniapps/application-multiple-containers/example/services.py
:language: python
Configuration
-------------
Listing of the ``config.yml``:
.. literalinclude:: ../../examples/miniapps/application-multiple-containers/config.yml
:language: yaml
Run the application
-------------------
You can find the source code and instructions for running on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/application-multiple-containers>`_.
.. disqus::

View File

@ -0,0 +1,93 @@
.. _application-single-container:
Application example (single container)
======================================
.. meta::
:keywords: Python,Dependency Injection,Inversion of Control,Container,Example,Application,
Framework,AWS,boto3,client
:description: This example shows how you can create an application using a single declarative
container. We build an example Python micro application following the dependency
injection principle. It consists from several services with a domain logic that
have dependencies on database & AWS S3.
This example shows how you can create an application using a single declarative container. Using
a single declarative container is a good choice for small or moderate size application. For
building a large application refer to :ref:`application-multiple-containers`.
We build an example micro application following the dependency injection principle. It consists
of several services with a domain logic. The services have dependencies on database & AWS S3.
.. image:: images/application.png
:width: 100%
:align: center
Start from the scratch or jump to the section:
.. contents::
:local:
:backlinks: none
You can find the source code and instructions for running on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/application-single-container>`_.
Application structure
---------------------
Application consists of an ``example`` package, several configuration files and a
``requirements.txt`` file.
.. code-block:: bash
./
├── example/
│ ├── __init__.py
│ ├── __main__.py
│ ├── containers.py
│ └── services.py
├── config.ini
├── logging.ini
└── requirements.txt
Container
---------
Listing of the ``example/containers.py``:
.. literalinclude:: ../../examples/miniapps/application-single-container/example/containers.py
:language: python
Main module
-----------
Listing of the ``example/__main__.py``:
.. literalinclude:: ../../examples/miniapps/application-single-container/example/__main__.py
:language: python
Services
--------
Listing of the ``example/services.py``:
.. literalinclude:: ../../examples/miniapps/application-single-container/example/services.py
:language: python
Configuration
-------------
Listing of the ``config.ini``:
.. literalinclude:: ../../examples/miniapps/application-single-container/config.ini
:language: ini
Listing of the ``logging.ini``:
.. literalinclude:: ../../examples/miniapps/application-single-container/logging.ini
:language: ini
Run the application
-------------------
You can find the source code and instructions for running on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/application-single-container>`_.
.. disqus::

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -10,5 +10,7 @@ Explore the examples to see the ``Dependency Injector`` in action.
.. toctree::
:maxdepth: 2
services-single-container
services-multiple-containers
application-single-container
application-multiple-containers
.. disqus::

View File

@ -1,73 +0,0 @@
Services mini application example (multiple containers)
=======================================================
.. meta::
:description: "Services miniapp" is an example mini application that
consists from several services that have dependencies on
some standard and 3rd-party libraries for logging,
interaction with database and remote service via API.
"Services miniapp" example demonstrates usage of
Dependency Injector for creating inversion of control /
dependency injection container.
"Services miniapp" is an example mini application that consists from several
services that have dependencies on some standard and 3rd-party libraries for
logging, interaction with database and remote service calls via API.
"Services miniapp" example demonstrates usage of
:doc:`Dependency Injector <../index>` for creating IoC container.
Instructions for running:
.. code-block:: bash
python run.py 1 secret photo.jpg
Example application
~~~~~~~~~~~~~~~~~~~
Classes diagram:
.. image:: /images/miniapps/services/classes.png
:width: 100%
:align: center
Example application structure:
.. code-block:: bash
/example
/__init__.py
/main.py
/services.py
Listing of ``example/services.py``:
.. literalinclude:: ../../examples/miniapps/services_v2/example/services.py
:language: python
Listing of ``example/main.py``:
.. literalinclude:: ../../examples/miniapps/services_v2/example/main.py
:language: python
IoC container
~~~~~~~~~~~~~
Listing of ``container.py``:
.. literalinclude:: ../../examples/miniapps/services_v2/container.py
:language: python
Run application
~~~~~~~~~~~~~~~
Listing of ``run.py``:
.. literalinclude:: ../../examples/miniapps/services_v2/run.py
:language: python
.. disqus::

View File

@ -1,82 +0,0 @@
Services mini application example (single container)
====================================================
.. meta::
:description: "Services miniapp" is an example mini application that
consists from several services that have dependencies on
some standard and 3rd-party libraries for logging,
interaction with database and remote service via API.
"Services miniapp" example demonstrates usage of
Dependency Injector for creating several inversion of control /
dependency injection containers.
"Services" is an example mini application. It consists from several services that have
dependencies on database & AWS S3.
.. image:: images/services-miniapp.png
:width: 100%
:align: center
Start from the scratch or jump to the section:
.. contents::
:local:
:backlinks: none
Application structure
---------------------
Application consists from ``example`` package, several configuration files and ``requirements.txt``.
.. code-block:: bash
./
├── example/
│ ├── __init__.py
│ ├── __main__.py
│ ├── containers.py
│ └── services.py
├── config.ini
├── logging.ini
└── requirements.txt
Container
---------
Listing of ``example/containers.py``:
.. literalinclude:: ../../examples/miniapps/services-single-container/example/containers.py
:language: python
Listing of ``example/__main__.py``:
.. literalinclude:: ../../examples/miniapps/services-single-container/example/__main__.py
:language: python
Services
--------
Listing of ``example/services.py``:
.. literalinclude:: ../../examples/miniapps/services-single-container/example/services.py
:language: python
Configuration
-------------
Listing of ``config.ini``:
.. literalinclude:: ../../examples/miniapps/services-single-container/config.ini
:language: ini
Listing of ``logging.ini``:
.. literalinclude:: ../../examples/miniapps/services-single-container/logging.ini
:language: ini
Sources on Github
-----------------
To find the source code navigate to the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/services-single-container>`_.
.. disqus::

View File

@ -129,9 +129,8 @@ Contents
:maxdepth: 2
introduction/index
main/installation
tutorials/index
examples/index
tutorials/index
providers/index
containers/index
examples-other/index

View File

@ -3,90 +3,90 @@ Dependency injection and inversion of control in Python
.. meta::
:keywords: Python,DI,Dependency injection,IoC,Inversion of Control
:description: This article describes benefits of dependency injection and
inversion of control for Python applications. Also it
contains some Python examples that show how dependency
injection and inversion could be implemented. In addition, it
demonstrates usage of dependency injection framework,
:description: This article describes benefits of dependency injection and
inversion of control for Python applications. Also it
contains some Python examples that show how dependency
injection and inversion could be implemented. In addition, it
demonstrates usage of dependency injection framework,
IoC container and such popular design pattern as Factory.
History
~~~~~~~
Originally, dependency injection pattern got popular in languages with static
typing, like Java. Dependency injection framework can
Originally, dependency injection pattern got popular in languages with static
typing, like Java. Dependency injection framework can
significantly improve flexibility of the language with static typing. Also,
implementation of dependency injection framework for language with static
typing is not something that one can do shortly, it could be quite complex
implementation of dependency injection framework for language with static
typing is not something that one can do shortly, it could be quite complex
thing to be done well.
While Python is very flexible interpreted language with dynamic typing, there
is a meaning that dependency injection doesn't work for it as well, as it does
for Java. Also there is a meaning that dependency injection framework is
While Python is very flexible interpreted language with dynamic typing, there
is a meaning that dependency injection doesn't work for it as well, as it does
for Java. Also there is a meaning that dependency injection framework is
something that Python developer would not ever need, cause dependency injection
could be implemented easily using language fundamentals.
Discussion
~~~~~~~~~~
It is true.
It is true.
Partly.
Dependency injection, as a software design pattern, has number of
Dependency injection, as a software design pattern, has number of
advantages that are common for each language (including Python):
+ Dependency Injection decreases coupling between a class and its dependency.
+ Because dependency injection doesn't require any change in code behavior it
can be applied to legacy code as a refactoring. The result is clients that
are more independent and that are easier to unit test in isolation using
stubs or mock objects that simulate other objects not under test. This ease
of testing is often the first benefit noticed when using dependency
+ Because dependency injection doesn't require any change in code behavior it
can be applied to legacy code as a refactoring. The result is clients that
are more independent and that are easier to unit test in isolation using
stubs or mock objects that simulate other objects not under test. This ease
of testing is often the first benefit noticed when using dependency
injection.
+ Dependency injection can be used to externalize a system's configuration
details into configuration files allowing the system to be reconfigured
without recompilation (rebuilding). Separate configurations can be written
for different situations that require different implementations of
+ Dependency injection can be used to externalize a system's configuration
details into configuration files allowing the system to be reconfigured
without recompilation (rebuilding). Separate configurations can be written
for different situations that require different implementations of
components. This includes, but is not limited to, testing.
+ Reduction of boilerplate code in the application objects since all work to
+ Reduction of boilerplate code in the application objects since all work to
initialize or set up dependencies is handled by a provider component.
+ Dependency injection allows a client to remove all knowledge of a concrete
implementation that it needs to use. This helps isolate the client from the
impact of design changes and defects. It promotes reusability, testability
+ Dependency injection allows a client to remove all knowledge of a concrete
implementation that it needs to use. This helps isolate the client from the
impact of design changes and defects. It promotes reusability, testability
and maintainability.
+ Dependency injection allows a client the flexibility of being configurable.
Only the client's behavior is fixed. The client may act on anything that
+ Dependency injection allows a client the flexibility of being configurable.
Only the client's behavior is fixed. The client may act on anything that
supports the intrinsic interface the client expects.
.. note::
While improved testability is one the first benefits of using dependency
injection, it could be easily overwhelmed by monkey-patching technique,
that works absolutely great in Python (you can monkey-patch anything,
anytime). At the same time, monkey-patching has nothing similar with
other advantages defined above. Also monkey-patching technique is
While improved testability is one the first benefits of using dependency
injection, it could be easily overwhelmed by monkey-patching technique,
that works absolutely great in Python (you can monkey-patch anything,
anytime). At the same time, monkey-patching has nothing similar with
other advantages defined above. Also monkey-patching technique is
something that could be considered like too dirty to be used in production.
The complexity of dependency injection pattern implementation in Python is
definitely quite lower than in other languages (even with dynamic typing).
The complexity of dependency injection pattern implementation in Python is
definitely quite lower than in other languages (even with dynamic typing).
.. note::
.. note::
Low complexity of dependency injection pattern implementation in Python
still means that some code should be written, reviewed, tested and
Low complexity of dependency injection pattern implementation in Python
still means that some code should be written, reviewed, tested and
supported.
Talking about inversion of control, it is a software design principle that
Talking about inversion of control, it is a software design principle that
also works for each programming language, not depending on its typing type.
Inversion of control is used to increase modularity of the program and make
Inversion of control is used to increase modularity of the program and make
it extensible.
Main design purposes of using inversion of control are:
+ To decouple the execution of a task from implementation.
+ To focus a module on the task it is designed for.
+ To free modules from assumptions about how other systems do what they do and
+ To free modules from assumptions about how other systems do what they do and
instead rely on contracts.
+ To prevent side effects when replacing a module.
@ -115,9 +115,9 @@ Next example demonstrates creation of several cars with different engines:
:language: python
While previous example demonstrates advantages of dependency injection, there
is a disadvantage demonstration as well - creation of car requires additional
code for specification of dependencies. Nevertheless, this disadvantage could
be easily avoided by using a dependency injection framework for creation of
is a disadvantage demonstration as well - creation of car requires additional
code for specification of dependencies. Nevertheless, this disadvantage could
be easily avoided by using a dependency injection framework for creation of
inversion of control container (IoC container).
Example of creation of several inversion of control containers (IoC containers)
@ -131,18 +131,21 @@ What's next?
Choose one of the following as a next step:
+ Pass one of the dependency injection tutorials:
+ :ref:`flask-tutorial`
+ :ref:`aiohttp-tutorial`
+ :ref:`asyncio-daemon-tutorial`
+ :ref:`cli-tutorial`
+ Know more about the :ref:`providers`
+ Go to the :ref:`contents`
- Look at application examples:
- :ref:`application-single-container`
- :ref:`application-multiple-containers`
- Pass the tutorials:
- :ref:`flask-tutorial`
- :ref:`aiohttp-tutorial`
- :ref:`asyncio-daemon-tutorial`
- :ref:`cli-tutorial`
- Know more about the :ref:`providers`
- Go to the :ref:`contents`
Useful links
~~~~~~~~~~~~
There are some useful links related to dependency injection design pattern
There are some useful links related to dependency injection design pattern
that could be used for further reading:
+ https://en.wikipedia.org/wiki/Dependency_injection

View File

@ -17,3 +17,4 @@ dependency injection pattern, inversion of control principle and
what_is_di
di_in_python
key_features
installation

View File

@ -31,7 +31,7 @@ Verification of currently installed version could be done using
>>> import dependency_injector
>>> dependency_injector.__version__
'3.15.2'
'3.38.0'
.. _PyPi: https://pypi.org/project/dependency-injector/
.. _GitHub: https://github.com/ets-labs/python-dependency-injector

View File

@ -175,13 +175,16 @@ What's next?
Choose one of the following as a next step:
+ Pass one of the tutorials:
+ :ref:`cli-tutorial`
+ :ref:`flask-tutorial`
+ :ref:`aiohttp-tutorial`
+ :ref:`asyncio-daemon-tutorial`
+ Know more about the :ref:`providers`
+ Go to the :ref:`contents`
- Look at application examples:
- :ref:`application-single-container`
- :ref:`application-multiple-containers`
- Pass the tutorials:
- :ref:`flask-tutorial`
- :ref:`aiohttp-tutorial`
- :ref:`asyncio-daemon-tutorial`
- :ref:`cli-tutorial`
- Know more about the :ref:`providers`
- Go to the :ref:`contents`
.. disqus::

View File

@ -1,5 +1,5 @@
Services mini application example (multiple containers)
=======================================================
Application example (multiple containers)
=========================================
Create virtual env:

View File

@ -1,5 +1,5 @@
Services mini application example (single container)
====================================================
Application example (single container)
======================================
Create virtual env: