From 68773576a77d9eec9bf72cc55ab793a1e5203387 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Fri, 9 Oct 2020 12:32:36 -0400 Subject: [PATCH] Update demo example --- README.rst | 18 +++++++++++-- docs/index.rst | 8 ++++-- docs/introduction/di_in_python.rst | 41 ++++++++++++------------------ docs/tutorials/aiohttp.rst | 2 +- docs/tutorials/asyncio-daemon.rst | 2 +- docs/tutorials/cli.rst | 2 +- docs/tutorials/flask.rst | 2 +- examples/demo/after.py | 8 +++--- examples/demo/before.py | 8 +++--- examples/demo/with_di.py | 4 +-- 10 files changed, 52 insertions(+), 43 deletions(-) diff --git a/README.rst b/README.rst index 31bd15e1..cb3290b7 100644 --- a/README.rst +++ b/README.rst @@ -107,9 +107,23 @@ Key features of the ``Dependency Injector``: container.config.timeout.from_env('TIMEOUT') container.wire(modules=[sys.modules[__name__]]) - main() + main() # <-- dependency is injected automatically -With the ``Dependency Injector`` you explicitly define and inject the dependencies. + with container.api_client.override(mock.Mock()): + main() # <-- overridden dependency is injected automatically + +When you call ``main()`` function the ``Service`` dependency is assembled and injected automatically. + +When doing a testing you call the ``container.api_client.override()`` to replace the real API +client with a mock. When you call ``main()`` the mock is injected. + +You can override any provider with another provider. + +It also helps you in configuring project for the different environments: replace an API client +with a stub on the dev or stage. + +With the ``Dependency Injector`` objects assembling is consolidated in the container. +Dependencies and injections are defined explicitly. This makes easier to understand and change how application works. .. figure:: https://raw.githubusercontent.com/wiki/ets-labs/python-dependency-injector/img/di-readme.svg diff --git a/docs/index.rst b/docs/index.rst index 0ee454fd..27312308 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -115,9 +115,13 @@ Key features of the ``Dependency Injector``: container.config.timeout.from_env('TIMEOUT') container.wire(modules=[sys.modules[__name__]]) - main() + main() # <-- dependency is injected automatically -With the ``Dependency Injector`` you explicitly define and inject the dependencies. + with container.api_client.override(mock.Mock()): + main() # <-- overridden dependency is injected automatically + +With the ``Dependency Injector`` objects assembling is consolidated in the container. +Dependencies and injections are defined explicitly. This makes easier to understand and change how application works. .. figure:: https://raw.githubusercontent.com/wiki/ets-labs/python-dependency-injector/img/di-readme.svg diff --git a/docs/introduction/di_in_python.rst b/docs/introduction/di_in_python.rst index 43d2f867..0f65b2d1 100644 --- a/docs/introduction/di_in_python.rst +++ b/docs/introduction/di_in_python.rst @@ -67,18 +67,18 @@ Before: class ApiClient: def __init__(self): - self.api_key = os.getenv('API_KEY') # <-- the dependency - self.timeout = os.getenv('TIMEOUT') # <-- the dependency + self.api_key = os.getenv('API_KEY') # <-- dependency + self.timeout = os.getenv('TIMEOUT') # <-- dependency class Service: def __init__(self): - self.api_client = ApiClient() # <-- the dependency + self.api_client = ApiClient() # <-- dependency def main() -> None: - service = Service() # <-- the dependency + service = Service() # <-- dependency ... @@ -95,17 +95,17 @@ After: class ApiClient: def __init__(self, api_key: str, timeout: int): - self.api_key = api_key # <-- the dependency is injected - self.timeout = timeout # <-- the dependency is injected + self.api_key = api_key # <-- dependency is injected + self.timeout = timeout # <-- dependency is injected class Service: def __init__(self, api_client: ApiClient): - self.api_client = api_client # <-- the dependency is injected + self.api_client = api_client # <-- dependency is injected - def main(service: Service): # <-- the dependency is injected + def main(service: Service): # <-- dependency is injected ... @@ -187,37 +187,28 @@ the dependency. if __name__ == '__main__': container = Container() - container.config.api_key.from_env('API_KEY') container.config.timeout.from_env('TIMEOUT') - container.wire(modules=[sys.modules[__name__]]) - main() + main() # <-- dependency is injected automatically -When you call ``main()`` function the ``Service`` dependency is assembled and injected:: + with container.api_client.override(mock.Mock()): + main() # <-- overridden dependency is injected automatically - main() - -Objects assembling is consolidated in the container. When you need to make a change you do it in -one place. +When you call ``main()`` function the ``Service`` dependency is assembled and injected automatically. When doing a testing you call the ``container.api_client.override()`` to replace the real API -client with a mock. When you call ``main()`` the mock is injected: - -.. code-block:: python - - from unittest import mock - - - with container.api_client.override(mock.Mock()): - main() +client with a mock. When you call ``main()`` the mock is injected. You can override any provider with another provider. It also helps you in configuring project for the different environments: replace an API client with a stub on the dev or stage. +Objects assembling is consolidated in the container. Dependencies and injections are defined explicitly. +This makes easier to understand and change how application works. + Testing, Monkey-patching and dependency injection ------------------------------------------------- diff --git a/docs/tutorials/aiohttp.rst b/docs/tutorials/aiohttp.rst index 05d864c6..f6bd083f 100644 --- a/docs/tutorials/aiohttp.rst +++ b/docs/tutorials/aiohttp.rst @@ -848,7 +848,7 @@ giphy client. We used :ref:`wiring` feature to inject the dependencies into the ``index()`` handler. :ref:`provider-overriding` feature helped in testing. -We kept all the dependencies injected explicitly. This will help when we need to add or +We kept all the dependencies injected explicitly. This will help when you need to add or change something in future. You can find complete project on the diff --git a/docs/tutorials/asyncio-daemon.rst b/docs/tutorials/asyncio-daemon.rst index ef651d6d..a279771d 100644 --- a/docs/tutorials/asyncio-daemon.rst +++ b/docs/tutorials/asyncio-daemon.rst @@ -1026,7 +1026,7 @@ With a help of :ref:`containers` and :ref:`providers` we have defined how to ass We used :ref:`wiring` feature to inject dispatcher into the ``main()`` function. :ref:`provider-overriding` feature helped in testing. -We kept all the dependencies injected explicitly. This will help when we need to add or +We kept all the dependencies injected explicitly. This will help when you need to add or change something in future. You can find complete project on the diff --git a/docs/tutorials/cli.rst b/docs/tutorials/cli.rst index 26350cd1..eba7531a 100644 --- a/docs/tutorials/cli.rst +++ b/docs/tutorials/cli.rst @@ -1055,7 +1055,7 @@ With a help of :ref:`containers` and :ref:`providers` we have defined how to ass We used :ref:`wiring` feature to inject the dependencies into the ``main()`` function. :ref:`provider-overriding` feature helped in testing. -We kept all the dependencies injected explicitly. This will help when we need to add or +We kept all the dependencies injected explicitly. This will help when you need to add or change something in future. You can find complete project on the diff --git a/docs/tutorials/flask.rst b/docs/tutorials/flask.rst index fce8a16b..54ceb73c 100644 --- a/docs/tutorials/flask.rst +++ b/docs/tutorials/flask.rst @@ -996,7 +996,7 @@ integrate it with a 3rd-party library. We used :ref:`wiring` feature to inject the dependencies into the ``index()`` view. :ref:`provider-overriding` feature helped in testing. -We kept all the dependencies injected explicitly. This will help when we need to add or +We kept all the dependencies injected explicitly. This will help when you need to add or change something in future. You can find complete project on the diff --git a/examples/demo/after.py b/examples/demo/after.py index 213f5a3c..1e8570c6 100644 --- a/examples/demo/after.py +++ b/examples/demo/after.py @@ -4,17 +4,17 @@ import os class ApiClient: def __init__(self, api_key: str, timeout: int): - self.api_key = api_key # <-- the dependency is injected - self.timeout = timeout # <-- the dependency is injected + self.api_key = api_key # <-- dependency is injected + self.timeout = timeout # <-- dependency is injected class Service: def __init__(self, api_client: ApiClient): - self.api_client = api_client # <-- the dependency is injected + self.api_client = api_client # <-- dependency is injected -def main(service: Service): # <-- the dependency is injected +def main(service: Service): # <-- dependency is injected ... diff --git a/examples/demo/before.py b/examples/demo/before.py index 895562c5..832d4863 100644 --- a/examples/demo/before.py +++ b/examples/demo/before.py @@ -4,18 +4,18 @@ import os class ApiClient: def __init__(self): - self.api_key = os.getenv('API_KEY') # <-- the dependency - self.timeout = os.getenv('TIMEOUT') # <-- the dependency + self.api_key = os.getenv('API_KEY') # <-- dependency + self.timeout = os.getenv('TIMEOUT') # <-- dependency class Service: def __init__(self): - self.api_client = ApiClient() # <-- the dependency + self.api_client = ApiClient() # <-- dependency def main() -> None: - service = Service() # <-- the dependency + service = Service() # <-- dependency ... diff --git a/examples/demo/with_di.py b/examples/demo/with_di.py index 17c68643..9fb5218f 100644 --- a/examples/demo/with_di.py +++ b/examples/demo/with_di.py @@ -33,7 +33,7 @@ if __name__ == '__main__': container.config.timeout.from_env('TIMEOUT') container.wire(modules=[sys.modules[__name__]]) - main() + main() # <-- dependency is injected automatically with container.api_client.override(mock.Mock()): - main() + main() # <-- overridden dependency is injected automatically