Update demo example

This commit is contained in:
Roman Mogylatov 2020-10-09 12:32:36 -04:00
parent 917abda16e
commit 68773576a7
10 changed files with 52 additions and 43 deletions

View File

@ -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

View File

@ -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

View File

@ -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
-------------------------------------------------

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
...

View File

@ -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
...

View File

@ -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