@@ -3,19 +3,20 @@ Dependency Injector - Dependency injection microframework for Python
33====================================================================
44
55*Dependency Injector * is a dependency injection microframework for Python.
6- It was designed to be unified, developer-friendly tool that helps to implement
7- dependency injection design pattern in formal, pretty, Pythonic way.
6+ It was designed to be a unified and developer-friendly tool that helps
7+ implement a dependency injection design pattern in a formal, pretty, and
8+ Pythonic way.
89
9- *Dependency Injector * framework key features are:
10+ The key features of the *Dependency Injector * framework are:
1011
11- + Easy, smart, pythonic style.
12- + Obvious, clear structure.
12+ + Easy, smart, and pythonic style.
13+ + Obvious and clear structure.
1314+ Extensibility and flexibility.
1415+ High performance.
1516+ Memory efficiency.
1617+ Thread safety.
17- + Documentation .
18- + Semantic versioning .
18+ + Documented .
19+ + Semantically versioned .
1920
2021*Dependency Injector * containers and providers are implemented as C extension
2122types using Cython.
@@ -63,46 +64,47 @@ Dependency injection
6364--------------------
6465
6566`Dependency injection `_ is a software design pattern that implements
66- `Inversion of control `_ for resolving dependencies. Formally, if object **A **
67+ `Inversion of control `_ to resolve dependencies. Formally, if object **A **
6768depends on object **B **, object **A ** must not create or import object **B **
68- directly. Instead of this object **A ** must provide a way for * injecting *
69- object **B **. The responsibilities of objects creation and dependencies
69+ directly. Instead of this object **A ** must provide a way to * inject *
70+ object **B **. The responsibilities of objects creation and dependency
7071injection are delegated to external code - the *dependency injector *.
7172
72- Popular terminology of dependency injection pattern:
73+ Popular terminology of the dependency injection pattern:
7374
74- + Object **A **, that is dependant on object **B **, is often called -
75+ + Object **A **, which depends on object **B **, is often called -
7576 the *client *.
76- + Object **B **, that is a dependency , is often called - the *service *.
77+ + Object **B **, which is depended on , is often called - the *service *.
7778+ External code that is responsible for creation of objects and injection
7879 of dependencies is often called - the *dependency injector *.
7980
80- There are several ways of how *service * can be injected into the *client *:
81+ There are several ways to inject a *service * into a *client *:
8182
82- + by passing it as ``__init__ `` argument (constructor / initializer injection)
83- + by setting it as attribute's value (attribute injection)
84- + by passing it as method's argument (method injection)
83+ + by passing it as an ``__init__ `` argument (constructor / initializer
84+ injection)
85+ + by setting it as an attribute's value (attribute injection)
86+ + by passing it as a method's argument (method injection)
8587
86- Dependency injection pattern has few strict rules that should be followed:
88+ The dependency injection pattern has few strict rules that should be followed:
8789
8890+ The *client * delegates to the *dependency injector * the responsibility
8991 of injecting its dependencies - the *service(s) *.
9092+ The *client * doesn't know how to create the *service *, it knows only
91- interface of the *service *. The *service * doesn't know that it is used by
93+ the interface of the *service *. The *service * doesn't know that it is used by
9294 the *client *.
9395+ The *dependency injector * knows how to create the *client * and
94- the *service *, it also knows that the *client * depends on the *service *,
96+ the *service *. It also knows that the *client * depends on the *service *,
9597 and knows how to inject the *service * into the *client *.
9698+ The *client * and the *service * know nothing about the *dependency injector *.
9799
98- Dependency injection pattern provides the following advantages:
100+ The dependency injection pattern provides the following advantages:
99101
100- + Control on application structure.
101- + Decreased coupling between application components.
102+ + Control of application structure.
103+ + Decreased coupling of application components.
102104+ Increased code reusability.
103105+ Increased testability.
104106+ Increased maintainability.
105- + Reconfiguration of system without rebuilding.
107+ + Reconfiguration of a system without rebuilding.
106108
107109Example of dependency injection
108110-------------------------------
@@ -153,7 +155,7 @@ Listing of ``example.cars`` module:
153155 """ Initializer."""
154156 self ._engine = engine # Engine is injected
155157
156- Next example demonstrates creation of several cars with different engines:
158+ The next example demonstrates the creation of several cars with different engines:
157159
158160.. code-block :: python
159161
@@ -168,14 +170,14 @@ Next example demonstrates creation of several cars with different engines:
168170 diesel_car = example.cars.Car(example.engines.DieselEngine())
169171 electro_car = example.cars.Car(example.engines.ElectroEngine())
170172
171- While previous example demonstrates advantages of dependency injection, there
172- is a disadvantage demonstration as well - creation of car requires additional
173- code for specification of dependencies. Nevertheless , this disadvantage could
174- be easily avoided by using a dependency injection framework for creation of
175- inversion of control container (IoC container).
173+ While the previous example demonstrates the advantages of dependency injection,
174+ there is a disadvantage demonstrated as well - the creation of a car requires
175+ additional code to specificaty its dependencies. However , this disadvantage
176+ could be avoided by using a dependency injection framework for the creation of
177+ an inversion of control container (IoC container).
176178
177- Example of creation of several inversion of control containers (IoC containers)
178- using *Dependency Injector *:
179+ Here's an example of the creation of several inversion of control containers
180+ (IoC containers) using *Dependency Injector *:
179181
180182.. code-block :: python
181183
@@ -219,9 +221,9 @@ using *Dependency Injector*:
219221 Dependency Injector structure
220222-----------------------------
221223
222- Dependency Injector is a microframework and has a very simple structure.
224+ * Dependency Injector * is a microframework and has a simple structure.
223225
224- There are 2 main entities: providers & containers.
226+ There are two main entities: providers and containers.
225227
226228.. image :: https://raw.githubusercontent.com/wiki/ets-labs/python-dependency-injector/img/internals.png
227229 :width: 100%
@@ -230,51 +232,51 @@ There are 2 main entities: providers & containers.
230232Providers
231233~~~~~~~~~
232234
233- Providers are strategies of accessing objects. They define how particular
235+ Providers describe strategies of accessing objects. They define how particular
234236objects are provided.
235237
236238- **Provider ** - base provider class.
237- - **Callable ** - provider that calls wrapped callable on every call. Supports
238- positional & keyword argument injections.
239+ - **Callable ** - provider that calls a wrapped callable on every call. Supports
240+ positional and keyword argument injections.
239241- **Factory ** - provider that creates new instance of specified class on every
240- call. Supports positional & keyword argument injections, as well as
242+ call. Supports positional and keyword argument injections, as well as
241243 attribute injections.
242- - **Singleton ** - provider that creates new instance of specified class on first
243- call and returns same instance on every next call. Supports positional &
244- keyword argument injections, as well as attribute injections.
244+ - **Singleton ** - provider that creates new instance of specified class on its
245+ first call and returns the same instance on every next call. Supports
246+ position and keyword argument injections, as well as attribute injections.
245247- **Object ** - provider that returns provided instance "as is".
246248- **ExternalDependency ** - provider that can be useful for development of
247- self-sufficient libraries / modules / applications that has required
248- external dependencies.
249+ self-sufficient libraries, modules, and applications that require external
250+ dependencies.
249251- **Configuration ** - provider that helps with implementing late static binding
250252 of configuration options - use first, define later.
251253
252254Containers
253255~~~~~~~~~~
254256
255- Containers are collections of providers. Main purpose of containers is to
257+ Containers are collections of providers. The main purpose of containers is to
256258group providers.
257259
258- - **DeclarativeContainer ** - is inversion of control container that could be
259- defined in declarative manner. It should cover most of the cases when list
260- of providers that would be included in container is deterministic
261- (container will not change its structure in runtime).
262- - **DynamicContainer ** - is an inversion of control container with dynamic
263- structure. It should cover most of the cases when list of providers that
264- would be included in container is non-deterministic and depends on
260+ - **DeclarativeContainer ** - is an inversion of control container that can be
261+ defined in a declarative manner. It covers most of the cases where a list of
262+ providers that is be included in a container is deterministic
263+ (that means the container will not change its structure in runtime).
264+ - **DynamicContainer ** - is an inversion of control container with a dynamic
265+ structure. It covers most of the cases where a list of providers that
266+ would be included in container is non-deterministic and depends on the
265267 application's flow or its configuration (container's structure could be
266- determined just after application will be started and will do some initial
267- work, like parsing list of container providers from the configuration).
268+ determined just after the application starts and might perform some initial
269+ work, like parsing a list of container providers from a configuration).
268270
269271Dependency Injector in action
270272-----------------------------
271273
272- Brief example below is a simplified version of inversion of control
273- container from one of the real-life applications. This example demonstrates
274- usage of *Dependency Injector * inversion of control container & providers
275- for specifying all application components and their dependencies between
276- each other in one module. Besides other listed above advantages, it gives a
277- great opportunity to control & manage application's structure in one place.
274+ The brief example below is a simplified version of inversion of control
275+ containers from a real-life application. The example demonstrates the usage
276+ of *Dependency Injector * inversion of control container and providers for
277+ specifying application components and their dependencies on each other in one
278+ module. Besides other previously mentioned advantages, it shows a great
279+ opportunity to control and manage application's structure in one place.
278280
279281.. code-block :: python
280282
@@ -336,7 +338,7 @@ great opportunity to control & manage application's structure in one place.
336338 photos_service = photos_service,
337339 )
338340
339- Next example demonstrates run of example application defined above:
341+ The next example demonstrates a run of the example application defined above:
340342
341343.. code-block :: python
342344
@@ -369,31 +371,31 @@ Next example demonstrates run of example application defined above:
369371 # Run application:
370372 container.main(* sys.argv[1 :])
371373
372- You can get more *Dependency Injector * examples in ``/examples `` directory on
373- GitHub:
374+ You can find more *Dependency Injector * examples in the ``/examples `` directory
375+ on our GitHub:
374376
375377 https://github.com/ets-labs/python-dependency-injector
376378
377379Installation
378380------------
379381
380- *Dependency Injector * library is available on `PyPi `_::
382+ The *Dependency Injector * library is available on `PyPi `_::
381383
382384 pip install dependency_injector
383385
384386Documentation
385387-------------
386388
387- *Dependency Injector * documentation is hosted on ReadTheDocs:
389+ The *Dependency Injector * documentation is hosted on ReadTheDocs:
388390
389391- `User's guide `_
390392- `API docs `_
391393
392394Feedback & Support
393395------------------
394396
395- Feel free to post questions, bugs, feature requests, proposals etc. on
396- *Dependency Injector * GitHub Issues :
397+ Feel free to post questions, bugs, feature requests, proposals, etc. on
398+ the *Dependency Injector * GitHub issues page :
397399
398400 https://github.com/ets-labs/python-dependency-injector/issues
399401
0 commit comments