8000 Update DI Demo 2 · bimec/python-dependency-injector@e0fa746 · GitHub
[go: up one dir, main page]

Skip to content

Commit e0fa746

Browse files
committed
Update DI Demo 2
1 parent e479e2c commit e0fa746

File tree

6 files changed

+105
-35
lines changed

6 files changed

+105
-35
lines changed

README.rst

Lines changed: 71 additions & 26 deletions
8000
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ What is ``Dependency Injector``?
5252

5353
``Dependency Injector`` is a dependency injection framework for Python.
5454

55-
It helps you implement the dependency injection principle.
55+
It helps you in implementing the dependency injection principle.
5656

5757
What is dependency injection?
5858
-----------------------------
@@ -70,6 +70,9 @@ Before:
7070

7171
.. code-block:: python
7272
73+
import os
74+
75+
7376
class ApiClient:
7477
7578
def __init__(self):
@@ -82,10 +85,18 @@ Before:
8285
def __init__(self):
8386
self.api_client = ApiClient()
8487
88+
89+
if __name__ == '__main__':
90+
service = Service()
91+
92+
8593
After:
8694

8795
.. code-block:: python
8896
97+
import os
98+
99+
89100
class ApiClient:
90101
91102
def __init__(self, api_key: str, timeout: int):
@@ -98,48 +109,82 @@ After:
98109
def __init__(self, api_client: ApiClient):
99110
self.api_client = api_client
100111
101-
Who creates the objects now? Look at the next section.
112+
113+
if __name__ == '__main__':
114+
service = Service(ApiClient(os.getenv('API_KEY'), os.getenv('TIMEOUT')))
115+
116+
117+
Flexibility comes with a price: now you need to assemble your objects like this
118+
``Service(ApiClient(os.getenv('API_KEY'), os.getenv('TIMEOUT')))``. The assembly code might get
119+
duplicated and it'll become harder to change the application structure.
102120

103121
What does Dependency Injector do?
104122
---------------------------------
105123

106-
``Dependency Injector`` provides you with the container and the providers that help you build
107-
your application objects when you apply dependency injection principle:
124+
``Dependency Injector`` helps you assemble the objects.
125+
126+
It provides you the container and the providers that help you describe objects assembly. When you
127+
need an object you get it from the container. The rest of the assembly work is done by the
128+
framework:
108129

109130
.. code-block:: python
110131
111-
from dependency_injector import containers, providers
112-
from unittest import mock
132+
from dependency_injector import containers, providers
133+
134+
135+
class ApiClient:
136+
137+
def __init__(self, api_key: str, timeout: int):
138+
self.api_key = api_key
139+
self.timeout = timeout
140+
113141
114-
from .example_di import ApiClient, Service
142+
class Service:
143+
144+
def __init__(self, api_client: ApiClient):
145+
self.api_client = api_client
115146
116147
117-
class Container(containers.DeclarativeContainer):
148+
class Container(containers.DeclarativeContainer):
118149
119-
config = providers.Configuration()
150+
config = providers.Configuration()
120151
121-
api_client = providers.Singleton(
122-
ApiClient,
123-
api_key=config.api_key,
124-
timeout=config.timeout,
125-
)
152+
api_client = providers.Singleton(
153+
ApiClient,
154+
api_key=config.api_key,
155+
timeout=config.timeout,
156+
)
126157
127-
service = providers.Factory(
128-
Service,
129-
api_client=api_client,
130-
)
158+
service = providers.Factory(
159+
Service,
160+
api_client=api_client,
161+
)
162+
163+
164+
if __name__ == '__main__':
165+
container = Container()
166+
container.config.api_key.from_env('API_KEY')
167+
container.config.timeout.from_env('TIMEOUT')
168+
169+
service = container.service()
170+
assert isinstance(service.api_client, ApiClient)
171+
172+
Retrieving of the ``Service`` instance now is done like this ``container.service()``.
173+
174+
Also ``Dependency Injector`` provides a bonus in overriding any of the providers with the
175+
``.override()`` method:
176+
177+
.. code-block:: python
131178
179+
from unittest import mock
132180
133-
if __name__ == '__main__':
134-
container = Container()
135-
container.config.from_yaml('config.yml')
136181
137-
service = container.service()
138-
assert isinstance(service.api_client, ApiClient)
182+
with container.api_client.override(mock.Mock()):
183+
service = container.service()
184+
assert isinstance(service.api_client, mock.Mock)
139185
140-
with container.api_client.override(mock.Mock()):
141-
service = container.service()
142-
assert isinstance(service.api_client, mock.Mock)
186+
It helps in a testing. Also you can use it for configuring project for the different environments:
187+
replace an API client with a stub on the dev or stage.
143188

144189
`More examples <https://github.com/ets-labs/python-dependency-injector/tree/master/examples>`_
145190

examples/di_demo2/config.yml

Lines changed: 0 additions & 2 deletions
This file was deleted.

examples/di_demo2/demo.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
from dependency_injector import containers, providers
2-
from unittest import mock
32

4-
from .example_di import ApiClient, Service
3+
4+
class ApiClient:
5+
6+
def __init__(self, api_key: str, timeout: int):
7+
self.api_key = api_key
8+
self.timeout = timeout
9+
10+
11+
class Service:
12+
13+
def __init__(self, api_client: ApiClient):
14+
self.api_client = api_client
515

616

717
class Container(containers.DeclarativeContainer):
@@ -22,11 +32,8 @@ class Container(containers.DeclarativeContainer):
2232

2333
if __name__ == '__main__':
2434
container = Container()
25-
container.config.from_yaml('config.yml')
35+
container.config.api_key.from_env('API_KEY')
36+
container.config.timeout.from_env('TIMEOUT')
2637

2738
service = container.service()
2839
assert isinstance(service.api_client, ApiClient)
29-
30-
with container.api_client.override(mock.Mock()):
31-
service = container.service()
32-
assert isinstance(service.api_client, mock.Mock)

examples/di_demo2/example_di.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12

23

34
class ApiClient:
@@ -11,3 +12,7 @@ class Service:
1112

1213
def __init__(self, api_client: ApiClient):
1314
self.api_client = api_client
15+
16+
17+
if __name__ == '__main__':
18+
service = Service(ApiClient(os.getenv('API_KEY'), os.getenv('TIMEOUT& CA11 #39;)))

examples/di_demo2/example_no_di.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ class Service:
1212

1313
def __init__(self):
1414
self.api_client = ApiClient()
15+
16+
17+
if __name__ == '__main__':
18+
service = Service()

examples/di_demo2/test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from unittest import mock
2+
3+
from demo import Container
4+
5+
6+
if __name__ == '__main__':
7+
container = Container()
8+
9+
with container.api_client.override(mock.Mock()):
10+
service = container.service()
11+
assert isinstance(service.api_client, mock.Mock)

0 commit comments

Comments
 (0)
0