|
| 1 | +Decoupled packages example (multiple containers) |
| 2 | +================================================ |
| 3 | + |
| 4 | +.. currentmodule:: dependency_injector.containers |
| 5 | + |
| 6 | +This example shows how to use ``Dependency Injector`` to create decoupled packages. |
| 7 | + |
| 8 | +To achieve a decoupling each package has a container with the components. When a component needs a |
| 9 | +dependency from the outside of the package scope we use the ``Dependency`` provider. The package |
| 10 | +container has no knowledge on where the dependencies come from. It states a need that the |
| 11 | +dependencies must be provided. This helps to decouple a package from the 3rd party dependencies |
| 12 | +and other packages. |
| 13 | + |
| 14 | +To wire the packages we use an application container. Application container has all 3rd party |
| 15 | +dependencies and package containers. It wires the packages and dependencies to create a |
| 16 | +complete application. |
| 17 | + |
| 18 | +We build an example micro application that consists from 3 packages: |
| 19 | + |
| 20 | +- ``user`` - a package with user domain logic, depends on a database |
| 21 | +- ``photo`` - a package with photo domain logic, depends on a database and AWS S3 |
| 22 | +- ``analytics`` - a package with analytics domain logic, depends on the ``user`` and ``photo`` |
| 23 | + package components |
| 24 | + |
| 25 | +.. image:: images/decoupled-packages.png |
| 26 | + :width: 100% |
| 27 | + :align: center |
| 28 | + |
| 29 | +Start from the scratch or jump to the section: |
| 30 | + |
| 31 | +.. contents:: |
| 32 | + :local: |
| 33 | + :backlinks: none |
| 34 | + |
| 35 | +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/decoupled-packages>`_. |
| 36 | + |
| 37 | +Application structure |
| 38 | +--------------------- |
| 39 | + |
| 40 | +Application consists of an ``example`` package, a configuration file and a ``requirements.txt`` |
| 41 | +file. |
| 42 | + |
| 43 | +.. code-block:: bash |
| 44 | +
|
| 45 | + ./ |
| 46 | + ├── example/ |
| 47 | + │ ├── analytics/ |
| 48 | + │ │ ├── __init__.py |
| 49 | + │ │ ├── containers.py |
| 50 | + │ │ └── services.py |
| 51 | + │ ├── photo/ |
| 52 | + │ │ ├── __init__.py |
| 53 | + │ │ ├── containers.py |
| 54 | + │ │ ├── entities.py |
| 55 | + │ │ └── repositories.py |
| 56 | + │ ├── user/ |
| 57 | + │ │ ├── __init__.py |
| 58 | + │ │ ├── containers.py |
| 59 | + │ │ ├── entities.py |
| 60 | + │ │ └── repositories.py |
| 61 | + │ ├── __init__.py |
| 62 | + │ ├── __main__.py |
| 63 | + │ └── containers.py |
| 64 | + ├── config.ini |
| 65 | + └── requirements.txt |
| 66 | +
|
| 67 | +Package containers |
| 68 | +------------------ |
| 69 | + |
| 70 | +Listing of the ``example/user/containers.py``: |
| 71 | + |
| 72 | +.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/user/containers.py |
| 73 | + :language: python |
| 74 | + |
| 75 | +Listing of the ``example/photo/containers.py``: |
| 76 | + |
| 77 | +.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/photo/containers.py |
| 78 | + :language: python |
| 79 | + |
| 80 | +Listing of the ``example/analytics/containers.py``: |
| 81 | + |
| 82 | +.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/analytics/containers.py |
| 83 | + :language: python |
| 84 | + |
| 85 | +Application container |
| 86 | +--------------------- |
| 87 | + |
| 88 | +Application container consists of all packages and 3rd party dependencies. Its role is to wire |
| 89 | +everything together in a complete application. |
| 90 | + |
| 91 | +Listing of the ``example/containers.py``: |
| 92 | + |
| 93 | +.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/containers.py |
| 94 | + :language: python |
| 95 | + |
| 96 | +.. note:: |
| 97 | + Package ``analytics`` has dependencies on the repositories from the ``user`` and |
| 98 | + ``photo`` packages. This is an example of how you can pass the dependencies from one package |
| 99 | + to another. |
| 100 | + |
| 101 | +Main module |
| 102 | +----------- |
| 103 | +Listing of the ``example/__main__.py``: |
| 104 | + |
| 105 | +.. literalinclude:: ../../examples/miniapps/decoupled-packages/example/__main__.py |
| 106 | + :language: python |
| 107 | + |
| 108 | +Configuration |
| 109 | +------------- |
| 110 | + |
| 111 | +Listing of the ``config.ini``: |
| 112 | + |
| 113 | +.. literalinclude:: ../../examples/miniapps/decoupled-packages/config.ini |
| 114 | + :language: ini |
| 115 | + |
| 116 | +Run the application |
| 117 | +------------------- |
| 118 | + |
| 119 | +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/decoupled-packages>`_. |
| 120 | + |
| 121 | +.. disqus:: |
0 commit comments