mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-28 20:44:01 +03:00
Update DI Demo 2
This commit is contained in:
parent
e479e2cb94
commit
e0fa746d7f
59
README.rst
59
README.rst
|
@ -52,7 +52,7 @@ What is ``Dependency Injector``?
|
|||
|
||||
``Dependency Injector`` is a dependency injection framework for Python.
|
||||
|
||||
It helps you implement the dependency injection principle.
|
||||
It helps you in implementing the dependency injection principle.
|
||||
|
||||
What is dependency injection?
|
||||
-----------------------------
|
||||
|
@ -70,6 +70,9 @@ Before:
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class ApiClient:
|
||||
|
||||
def __init__(self):
|
||||
|
@ -82,10 +85,18 @@ Before:
|
|||
def __init__(self):
|
||||
self.api_client = ApiClient()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
service = Service()
|
||||
|
||||
|
||||
After:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class ApiClient:
|
||||
|
||||
def __init__(self, api_key: str, timeout: int):
|
||||
|
@ -98,20 +109,40 @@ After:
|
|||
def __init__(self, api_client: ApiClient):
|
||||
self.api_client = api_client
|
||||
|
||||
Who creates the objects now? Look at the next section.
|
||||
|
||||
if __name__ == '__main__':
|
||||
service = Service(ApiClient(os.getenv('API_KEY'), os.getenv('TIMEOUT')))
|
||||
|
||||
|
||||
Flexibility comes with a price: now you need to assemble your objects like this
|
||||
``Service(ApiClient(os.getenv('API_KEY'), os.getenv('TIMEOUT')))``. The assembly code might get
|
||||
duplicated and it'll become harder to change the application structure.
|
||||
|
||||
What does Dependency Injector do?
|
||||
---------------------------------
|
||||
|
||||
``Dependency Injector`` provides you with the container and the providers that help you build
|
||||
your application objects when you apply dependency injection principle:
|
||||
``Dependency Injector`` helps you assemble the objects.
|
||||
|
||||
It provides you the container and the providers that help you describe objects assembly. When you
|
||||
need an object you get it from the container. The rest of the assembly work is done by the
|
||||
framework:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from dependency_injector import containers, providers
|
||||
from unittest import mock
|
||||
|
||||
from .example_di import ApiClient, Service
|
||||
|
||||
class ApiClient:
|
||||
|
||||
def __init__(self, api_key: str, timeout: int):
|
||||
self.api_key = api_key
|
||||
self.timeout = timeout
|
||||
|
||||
|
||||
class Service:
|
||||
|
||||
def __init__(self, api_client: ApiClient):
|
||||
self.api_client = api_client
|
||||
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
|
@ -132,15 +163,29 @@ your application objects when you apply dependency injection principle:
|
|||
|
||||
if __name__ == '__main__':
|
||||
container = Container()
|
||||
container.config.from_yaml('config.yml')
|
||||
container.config.api_key.from_env('API_KEY')
|
||||
container.config.timeout.from_env('TIMEOUT')
|
||||
|
||||
service = container.service()
|
||||
assert isinstance(service.api_client, ApiClient)
|
||||
|
||||
Retrieving of the ``Service`` instance now is done like this ``container.service()``.
|
||||
|
||||
Also ``Dependency Injector`` provides a bonus in overriding any of the providers with the
|
||||
``.override()`` method:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from unittest import mock
|
||||
|
||||
|
||||
with container.api_client.override(mock.Mock()):
|
||||
service = container.service()
|
||||
assert isinstance(service.api_client, mock.Mock)
|
||||
|
||||
It helps in a testing. Also you can use it for configuring project for the different environments:
|
||||
replace an API client with a stub on the dev or stage.
|
||||
|
||||
`More examples <https://github.com/ets-labs/python-dependency-injector/tree/master/examples>`_
|
||||
|
||||
Installation
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
api_key: test-key
|
||||
timeout: 5
|
|
@ -1,7 +1,17 @@
|
|||
from dependency_injector import containers, providers
|
||||
from unittest import mock
|
||||
|
||||
from .example_di import ApiClient, Service
|
||||
|
||||
class ApiClient:
|
||||
|
||||
def __init__(self, api_key: str, timeout: int):
|
||||
self.api_key = api_key
|
||||
self.timeout = timeout
|
||||
|
||||
|
||||
class Service:
|
||||
|
||||
def __init__(self, api_client: ApiClient):
|
||||
self.api_client = api_client
|
||||
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
|
@ -22,11 +32,8 @@ class Container(containers.DeclarativeContainer):
|
|||
|
||||
if __name__ == '__main__':
|
||||
container = Container()
|
||||
container.config.from_yaml('config.yml')
|
||||
container.config.api_key.from_env('API_KEY')
|
||||
container.config.timeout.from_env('TIMEOUT')
|
||||
|
||||
service = container.service()
|
||||
assert isinstance(service.api_client, ApiClient)
|
||||
|
||||
with container.api_client.override(mock.Mock()):
|
||||
service = container.service()
|
||||
assert isinstance(service.api_client, mock.Mock)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
|
||||
|
||||
class ApiClient:
|
||||
|
@ -11,3 +12,7 @@ class Service:
|
|||
|
||||
def __init__(self, api_client: ApiClient):
|
||||
self.api_client = api_client
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
service = Service(ApiClient(os.getenv('API_KEY'), os.getenv('TIMEOUT')))
|
||||
|
|
|
@ -12,3 +12,7 @@ class Service:
|
|||
|
||||
def __init__(self):
|
||||
self.api_client = ApiClient()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
service = Service()
|
||||
|
|
11
examples/di_demo2/test.py
Normal file
11
examples/di_demo2/test.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from unittest import mock
|
||||
|
||||
from demo import Container
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
container = Container()
|
||||
|
||||
with container.api_client.override(mock.Mock()):
|
||||
service = container.service()
|
||||
assert isinstance(service.api_client, mock.Mock)
|
Loading…
Reference in New Issue
Block a user