mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 02:53:56 +03:00
Update README
This commit is contained in:
parent
7e11d56ad6
commit
b4772af2c1
47
README.rst
47
README.rst
|
@ -70,7 +70,7 @@ Coupling and cohesion are about how tough the components are tied.
|
||||||
|
|
||||||
When the cohesion is high the coupling is low.
|
When the cohesion is high the coupling is low.
|
||||||
|
|
||||||
Low coupling and high cohesion brings a flexibility. Your code becomes easier to change and test.
|
Low coupling brings a flexibility. Your code becomes easier to change and test.
|
||||||
|
|
||||||
How to implement dependency injection?
|
How to implement dependency injection?
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
@ -124,7 +124,6 @@ After:
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
service = Service(ApiClient(os.getenv('API_KEY'), os.getenv('TIMEOUT')))
|
service = Service(ApiClient(os.getenv('API_KEY'), os.getenv('TIMEOUT')))
|
||||||
|
|
||||||
|
|
||||||
``ApiClient`` is decoupled from knowing where the options come from. You can read a key and a
|
``ApiClient`` is decoupled from knowing where the options come from. You can read a key and a
|
||||||
timeout from a configuration file or even get them from a database.
|
timeout from a configuration file or even get them from a database.
|
||||||
|
|
||||||
|
@ -133,16 +132,23 @@ stub or other compatible object.
|
||||||
|
|
||||||
Flexibility comes with a price.
|
Flexibility comes with a price.
|
||||||
|
|
||||||
Now you need to assemble your objects like this
|
Now you need to assemble the 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?
|
service = 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.
|
||||||
|
|
||||||
|
Here comes the ``Dependency Injector``.
|
||||||
|
|
||||||
|
What does the Dependency Injector do?
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
With the dependency injection pattern objects lose the responsibility of assembling the
|
||||||
|
dependencies. The ``Dependency Injector`` absorbs that responsibility.
|
||||||
|
|
||||||
``Dependency Injector`` helps to assemble the objects.
|
``Dependency Injector`` helps to assemble the objects.
|
||||||
|
|
||||||
It provides you the container and the providers that help you describe objects assembly. When you
|
It provides a container and providers that help you with the objects assembly. When you
|
||||||
need an object you get it from the container. The rest of the assembly work is done by the
|
need an object you get it from the container. The rest of the assembly work is done by the
|
||||||
framework:
|
framework:
|
||||||
|
|
||||||
|
@ -151,19 +157,6 @@ framework:
|
||||||
from dependency_injector import containers, providers
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
|
||||||
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):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
config = providers.Configuration()
|
config = providers.Configuration()
|
||||||
|
@ -187,12 +180,14 @@ framework:
|
||||||
|
|
||||||
service = container.service()
|
service = container.service()
|
||||||
|
|
||||||
Retrieving of the ``Service`` instance now is done like this ``container.service()``.
|
Retrieving of the ``Service`` instance now is done like this::
|
||||||
|
|
||||||
|
service = container.service()
|
||||||
|
|
||||||
Objects assembling is consolidated in the container. When you need to make a change you do it in
|
Objects assembling is consolidated in the container. When you need to make a change you do it in
|
||||||
one place.
|
one place.
|
||||||
|
|
||||||
When doing the testing you call the ``container.api_client.override()`` to replace the real API
|
When doing a testing you call the ``container.api_client.override()`` to replace the real API
|
||||||
client with a mock:
|
client with a mock:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
@ -203,8 +198,10 @@ client with a mock:
|
||||||
with container.api_client.override(mock.Mock()):
|
with container.api_client.override(mock.Mock()):
|
||||||
service = container.service()
|
service = container.service()
|
||||||
|
|
||||||
It helps in a testing. Also you can use it for configuring project for the different environments:
|
You can override any provider by another provider.
|
||||||
replace an API client with a stub on the dev or stage.
|
|
||||||
|
It also helps you in 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>`_
|
`More examples <https://github.com/ets-labs/python-dependency-injector/tree/master/examples>`_
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,17 @@ Dependency injection and inversion of control in Python
|
||||||
|
|
||||||
.. meta::
|
.. meta::
|
||||||
:keywords: Python,DI,Dependency injection,IoC,Inversion of Control,Example
|
:keywords: Python,DI,Dependency injection,IoC,Inversion of Control,Example
|
||||||
:description: This page describes a usage of the dependency injection pattern in Python. It
|
:description: This page describes a usage of the dependency injection and inversion of control
|
||||||
contains Python examples that show how to implement dependency injection. It
|
in Python. It contains Python examples that show how to implement dependency
|
||||||
demonstrates a usage of the dependency injection framework
|
injection. It demonstrates a usage of the dependency injection framework
|
||||||
Dependency Injector, its container, Factory, Singleton and Configuration
|
Dependency Injector, its container, Factory, Singleton and Configuration
|
||||||
providers. The example show how to use Dependency Injector providers overriding
|
providers. The example show how to use Dependency Injector providers overriding
|
||||||
feature for testing or configuring project in different environments and explains
|
feature for testing or configuring project in different environments and explains
|
||||||
why it's better then monkey-patching.
|
why it's better then monkey-patching.
|
||||||
|
|
||||||
Originally dependency injection pattern got popular in the languages with a static typing,
|
Originally dependency injection pattern got popular in the languages with a static typing,
|
||||||
like Java. Dependency injection framework can significantly improve flexibility of the language
|
like Java. Dependency injection is a principle that helps to achieve an inversion of control.
|
||||||
|
Dependency injection framework can significantly improve a flexibility of the language
|
||||||
with a static typing. Implementation of a dependency injection framework for a language
|
with a static typing. Implementation of a dependency injection framework for a language
|
||||||
with a static typing is not something that one can do quickly. It will be a quite complex thing
|
with a static typing is not something that one can do quickly. It will be a quite complex thing
|
||||||
to be done well. And will take time.
|
to be done well. And will take time.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user