Skip to content

Commit 7eed1cf

Browse files
committed
Update Factory provider docs and examples
1 parent 556c842 commit 7eed1cf

16 files changed

+107
-91
lines changed

docs/catalogs/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Also, for both of these and some other cases, it might be useful to attach
1616
some init / shutdown functionality or something else, that deals with group
1717
of providers.
1818

19+
Catalogs module API docs - :py:mod:`dependency_injector.catalogs`.
20+
1921
.. toctree::
2022
:maxdepth: 2
2123

docs/images/providers/factory.png

10.9 KB
Loading
66 KB
Loading
37.3 KB
Loading
27.1 KB
Loading
23.1 KB
Loading
38.1 KB
Loading
40.7 KB
Loading

docs/providers/factory.rst

Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
Factory providers
22
-----------------
33

4-
``di.Factory`` provider creates new instance of specified class on every call.
4+
.. module:: dependency_injector.providers
5+
6+
:py:class:`Factory` provider creates new instance of specified class on every
7+
call.
58

69
Nothing could be better than brief example:
710

@@ -15,21 +18,22 @@ Nothing could be better than brief example:
1518
Factory providers and __init__ injections
1619
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1720

18-
``di.Factory`` takes a various number of positional and keyword arguments that
19-
are used as ``__init__()`` injections. Every time, when ``di.Factory``
20-
creates new one instance, positional and keyword argument injections would be
21-
passed as an instance's arguments.
21+
:py:class:`Factory` takes a various number of positional and keyword arguments
22+
that are used as ``__init__()`` injections. Every time, when
23+
:py:class:`Factory` creates new one instance, positional and keyword
24+
argument injections would be passed as an instance's arguments.
2225

2326
Such behaviour is very similar to the standard Python ``functools.partial``
2427
object, except of one thing: all injectable values are provided
25-
*"as is"*, except of providers (subclasses of ``di.Provider``). Providers
28+
*"as is"*, except of providers (subclasses of :py:class:`Provider`). Providers
2629
will be called every time, when injection needs to be done. For example,
27-
if injectable value of injection is a ``di.Factory``, it will provide new one
28-
instance (as a result of its call) every time, when injection needs to be done.
30+
if injectable value of injection is a :py:class:`Factory`, it will provide
31+
new one instance (as a result of its call) every time, when injection needs
32+
to be done.
2933

3034
Example below is a little bit more complicated. It shows how to create
31-
``di.Factory`` of particular class with ``__init__()`` argument injections
32-
which injectable values are also provided by another factories:
35+
:py:class:`Factory` of particular class with ``__init__()`` argument
36+
injections which injectable values are also provided by another factories:
3337

3438
.. note::
3539

@@ -58,14 +62,14 @@ Example of usage keyword argument injections:
5862
Factory providers and __init__ injections priority
5963
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6064

61-
Next example shows how ``di.Factory`` provider deals with positional and
62-
keyword ``__init__()`` context arguments. In few words, ``di.Factory``
65+
Next example shows how :py:class:`Factory` provider deals with positional and
66+
keyword ``__init__()`` context arguments. In few words, :py:class:`Factory`
6367
behaviour here is very like a standard Python ``functools.partial``:
6468

65-
- Positional context arguments will be appended after ``di.Factory``
69+
- Positional context arguments will be appended after :py:class:`Factory`
6670
positional injections.
67-
- Keyword context arguments have priority on ``di.Factory`` keyword injections
68-
and will be merged over them.
71+
- Keyword context arguments have priority on :py:class:`Factory` keyword
72+
injections and will be merged over them.
6973

7074
So, please, follow the example below:
7175

@@ -82,34 +86,38 @@ Objects can take dependencies in different forms (some objects take init
8286
arguments, other use attributes setting or method calls). It affects how
8387
such objects are created and initialized.
8488

85-
``di.Factory`` provider takes various number of positional and keyword
89+
:py:class:`Factory` provider takes various number of positional and keyword
8690
arguments, that define what kinds of dependency injections have to be used.
8791

88-
All of those instructions are defined in ``di.injections`` module and are
89-
subclasses of ``di.injections.Injection`` (shortcut ``di.Injection``). There
90-
are several types of injections that are used by ``di.Factory`` provider:
91-
92-
+ ``di.Arg`` - injection is done by passing injectable value in object's
93-
``__init__()`` method in time of object's creation as positional argument.
94-
Takes injectable value only.
95-
+ ``di.KwArg`` - injection is done by passing injectable value in object's
96-
``__init__()`` method in time of object's creation as keyword argument.
97-
Takes keyword name of ``__init__()`` argument and injectable value.
98-
+ ``di.Attribute`` - injection is done by setting specified attribute with
99-
injectable value right after object's creation. Takes attribute's name
100-
and injectable value.
101-
+ ``di.Method`` - injection is done by calling of specified method with
102-
injectable value right after object's creation and attribute injections
103-
are done. Takes method name and injectable value.
104-
105-
All ``di.Injection``'s injectable values are provided *"as is"*, except of
106-
providers (subclasses of ``di.Provider``). Providers will be called every time,
107-
when injection needs to be done.
92+
All of those instructions are defined in
93+
:py:mod:`dependency_injector.injections` module and are subclasses of
94+
:py:class:`dependency_injector.injections.Injection`. There are several types
95+
of injections that are used by :py:class:`Factory` provider:
96+
97+
+ :py:class:`dependency_injector.injections.Arg` - injection is done by
98+
passing injectable value in object's ``__init__()`` method in time of
99+
object's creation as positional argument. Takes injectable value only.
100+
+ :py:class:`dependency_injector.injections.KwArg` - injection is done by
101+
passing injectable value in object's ``__init__()`` method in time of
102+
object's creation as keyword argument. Takes keyword name of
103+
``__init__()`` argument and injectable value.
104+
+ :py:class:`dependency_injector.injections.Attribute` - injection is done
105+
by setting specified attribute with injectable value right after
106+
object's creation. Takes attribute's name and injectable value.
107+
+ :py:class:`dependency_injector.injections.Method` - injection is done by
108+
calling of specified method with injectable value right after object's
109+
creation and attribute injections are done. Takes method name and
110+
injectable value.
111+
112+
All :py:class:`dependency_injector.injections.Injection`'s injectable values
113+
are provided *"as is"*, except of providers (subclasses of
114+
:py:class:`Provider`). Providers will be called every time, when injection
115+
needs to be done.
108116

109117
Factory providers and attribute injections
110118
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
111119

112-
Example below shows how to create ``di.Factory`` of particular class with
120+
Example below shows how to create :py:class:`Factory` of particular class with
113121
attribute injections. Those injections are done by setting specified attributes
114122
with injectable values right after object's creation.
115123

@@ -123,10 +131,10 @@ Example:
123131
Factory providers and method injections
124132
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
125133

126-
Current example shows how to create ``di.Factory`` of particular class with
127-
method injections. Those injections are done by calling of specified method
128-
with injectable value right after object's creation and attribute injections
129-
are done.
134+
Current example shows how to create :py:class:`Factory` of particular class
135+
with method injections. Those injections are done by calling of specified
136+
method with injectable value right after object's creation and attribute
137+
injections are done.
130138

131139
Method injections are not very popular in Python due Python best practices
132140
(usage of public attributes instead of setter methods), but they may appear in
@@ -142,21 +150,21 @@ Example:
142150
Factory providers delegation
143151
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144152

145-
``di.Factory`` provider could be delegated to any other provider via any kind
146-
of injection. As it was mentioned earlier, if ``di.Factory`` is injectable
147-
value, it will be called every time when injection is done. ``di.Factory``
148-
delegation is performed by wrapping delegated ``di.Factory`` into special
149-
provider type - ``di.Delegate``, that just returns wrapped ``di.Factory``.
150-
Saying in other words, delegation of factories - is a way to inject factories
151-
themselves, instead of results of their calls.
152-
153+
:py:class:`Factory` provider could be delegated to any other provider via any
154+
kind of injection. As it was mentioned earlier, if :py:class:`Factory` is
155+
injectable value, it will be called every time when injection is done.
156+
:py:class:`Factory` delegation is performed by wrapping delegated
157+
:py:class:`Factory` into special provider type - :py:class:`Delegate`, that
158+
just returns wrapped :py:class:`Factory`. Saying in other words, delegation
159+
of factories - is a way to inject factories themselves, instead of results
160+
of their calls.
153161

154162
Actually, there are two ways of creating factory delegates:
155163

156-
+ ``di.Delegate(di.Factory(...))`` - obviously wrapping factory into
157-
``di.Delegate`` provider.
158-
+ ``di.Factory(...).delegate()`` - calling factory ``delegate()`` method, that
159-
returns delegate wrapper for current factory.
164+
+ ``Delegate(Factory(...))`` - obviously wrapping factory into
165+
:py:class:`Delegate` provider.
166+
+ ``Factory(...).delegate()`` - calling factory :py:meth:`Factory.delegate`
167+
method, that returns delegate wrapper for current factory.
160168

161169
Example:
162170

examples/providers/factory.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
"""`di.Factory` providers example."""
1+
"""`Factory` providers example."""
22

3-
import dependency_injector as di
3+
from dependency_injector import providers
44

55

66
class User(object):
77
"""Example class User."""
88

99
# Factory provider creates new instance of specified class on every call.
10-
users_factory = di.Factory(User)
10+
users_factory = providers.Factory(User)
1111

1212
# Creating several User objects:
1313
user1 = users_factory()

0 commit comments

Comments
 (0)