diff --git a/docs/images/miniapps/engines_cars/diagram.png b/docs/images/miniapps/engines_cars/diagram.png new file mode 100644 index 00000000..6320bfdd Binary files /dev/null and b/docs/images/miniapps/engines_cars/diagram.png differ diff --git a/docs/introduction/di_in_python.rst b/docs/introduction/di_in_python.rst index 8411403f..c7cf6b91 100644 --- a/docs/introduction/di_in_python.rst +++ b/docs/introduction/di_in_python.rst @@ -93,35 +93,36 @@ Example Let's go through next example: -.. literalinclude:: ../../examples/ioc_di_demos/car_engine.py +.. image:: /images/miniapps/engines_cars/diagram.png + :width: 100% + :align: center + +Listing of ``example.engines`` module: + +.. literalinclude:: ../../examples/miniapps/engines_cars/example/engines.py :language: python :linenos: -``Car`` **creates** an ``Engine`` during its creation. Really? Does it make -more sense than creating an ``Engine`` separately and then -**inject (put) it into** ``Car`` when ``Car`` is being created? +Listing of ``example.cars`` module: -.. literalinclude:: ../../examples/ioc_di_demos/car_engine_ioc.py +.. literalinclude:: ../../examples/miniapps/engines_cars/example/cars.py :language: python :linenos: -Previous example may look more obvious and gives a chance to start getting -other benefits of dependency injection and inversion of control, but creation -of ``Car`` instances became a bit harder cause now ``Engine`` injections -should be done manually every time when ``Car`` instances are being created. +Next example demonstrates creation of several cars with different engines: -Let's automate ``Engine`` into ``Car`` injections using *Dependency Injector*: - - -.. literalinclude:: ../../examples/ioc_di_demos/car_engine_ioc_container.py +.. literalinclude:: ../../examples/miniapps/engines_cars/example_di.py :language: python :linenos: -.. note:: +While previous example demonstrates advantage 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 creating inversion of control container (IoC container). - ``Container`` from previous example is an inversion of control container. - It contains a collection of component providers that could be injected - into each other. +Example of creation of several inversion of control containers (IoC containers) +using *Dependency Injector*: - Assuming this, ``Container`` could be one and the only place, where - application's structure is being managed on the high level. +.. literalinclude:: ../../examples/miniapps/engines_cars/example_ioc_containers.py + :language: python + :linenos: diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index 3a9e6304..fea54aa1 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -12,6 +12,7 @@ Development version .. - No features. - Add github badges to readme and docs index pages. - Update service names in services example miniapp. +- Create engines & cars example miniapp. 2.2.8 ----- diff --git a/examples/miniapps/engines_cars/README.rst b/examples/miniapps/engines_cars/README.rst new file mode 100644 index 00000000..b36b02b6 --- /dev/null +++ b/examples/miniapps/engines_cars/README.rst @@ -0,0 +1,9 @@ +Engines & Cars Dependency Injection Example +=========================================== + +Instructions for running: + +.. code-block:: bash + + python example_di.py + python example_ioc_containers.py diff --git a/examples/miniapps/engines_cars/example/__init__.py b/examples/miniapps/engines_cars/example/__init__.py new file mode 100644 index 00000000..bfa99aa2 --- /dev/null +++ b/examples/miniapps/engines_cars/example/__init__.py @@ -0,0 +1 @@ +"""Example top-level package.""" diff --git a/examples/miniapps/engines_cars/example/cars.py b/examples/miniapps/engines_cars/example/cars.py new file mode 100644 index 00000000..a1ddc027 --- /dev/null +++ b/examples/miniapps/engines_cars/example/cars.py @@ -0,0 +1,9 @@ +"""Dependency injection example, cars module.""" + + +class Car(object): + """Example car.""" + + def __init__(self, engine): + """Initializer.""" + self._engine = engine # Engine is injected diff --git a/examples/miniapps/engines_cars/example/engines.py b/examples/miniapps/engines_cars/example/engines.py new file mode 100644 index 00000000..8e42ec1d --- /dev/null +++ b/examples/miniapps/engines_cars/example/engines.py @@ -0,0 +1,21 @@ +"""Dependency injection example, engines module.""" + + +class Engine(object): + """Example engine base class. + + Engine is a heart of every car. Engine is a very common term and could be + implemented in very different ways. + """ + + +class GasolineEngine(Engine): + """Gasoline engine.""" + + +class DieselEngine(Engine): + """Diesel engine.""" + + +class ElectroEngine(Engine): + """Electro engine.""" diff --git a/examples/miniapps/engines_cars/example_di.py b/examples/miniapps/engines_cars/example_di.py new file mode 100644 index 00000000..317d7d8f --- /dev/null +++ b/examples/miniapps/engines_cars/example_di.py @@ -0,0 +1,10 @@ +"""Dependency injection example, Cars & Engines.""" + +import example.cars +import example.engines + + +if __name__ == '__main__': + gasoline_car = example.cars.Car(example.engines.GasolineEngine()) + diesel_car = example.cars.Car(example.engines.DieselEngine()) + electro_car = example.cars.Car(example.engines.ElectroEngine()) diff --git a/examples/miniapps/engines_cars/example_ioc_containers.py b/examples/miniapps/engines_cars/example_ioc_containers.py new file mode 100644 index 00000000..b97ab121 --- /dev/null +++ b/examples/miniapps/engines_cars/example_ioc_containers.py @@ -0,0 +1,36 @@ +"""Dependency injection example, Cars & Engines IoC containers.""" + +import example.cars +import example.engines + +import dependency_injector.containers as containers +import dependency_injector.providers as providers + + +class Engines(containers.DeclarativeContainer): + """IoC container of engine providers.""" + + gasoline = providers.Factory(example.engines.GasolineEngine) + + diesel = providers.Factory(example.engines.DieselEngine) + + electro = providers.Factory(example.engines.ElectroEngine) + + +class Cars(containers.DeclarativeContainer): + """IoC container of car providers.""" + + gasoline = providers.Factory(example.cars.Car, + engine=Engines.gasoline) + + diesel = providers.Factory(example.cars.Car, + engine=Engines.diesel) + + electro = providers.Factory(example.cars.Car, + engine=Engines.electro) + + +if __name__ == '__main__': + gasoline_car = Cars.gasoline() + diesel_car = Cars.diesel() + electro_car = Cars.electro()