Update Factory provider docs and examples
|
@ -16,6 +16,8 @@ Also, for both of these and some other cases, it might be useful to attach
|
|||
some init / shutdown functionality or something else, that deals with group
|
||||
of providers.
|
||||
|
||||
Catalogs module API docs - :py:mod:`dependency_injector.catalogs`.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
|
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 19 KiB |
BIN
docs/images/providers/factory_attribute_injection.png
Normal file
After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 72 KiB |
|
@ -1,7 +1,10 @@
|
|||
Factory providers
|
||||
-----------------
|
||||
|
||||
``di.Factory`` provider creates new instance of specified class on every call.
|
||||
.. module:: dependency_injector.providers
|
||||
|
||||
:py:class:`Factory` provider creates new instance of specified class on every
|
||||
call.
|
||||
|
||||
Nothing could be better than brief example:
|
||||
|
||||
|
@ -15,21 +18,22 @@ Nothing could be better than brief example:
|
|||
Factory providers and __init__ injections
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``di.Factory`` takes a various number of positional and keyword arguments that
|
||||
are used as ``__init__()`` injections. Every time, when ``di.Factory``
|
||||
creates new one instance, positional and keyword argument injections would be
|
||||
passed as an instance's arguments.
|
||||
:py:class:`Factory` takes a various number of positional and keyword arguments
|
||||
that are used as ``__init__()`` injections. Every time, when
|
||||
:py:class:`Factory` creates new one instance, positional and keyword
|
||||
argument injections would be passed as an instance's arguments.
|
||||
|
||||
Such behaviour is very similar to the standard Python ``functools.partial``
|
||||
object, except of one thing: all injectable values are provided
|
||||
*"as is"*, except of providers (subclasses of ``di.Provider``). Providers
|
||||
*"as is"*, except of providers (subclasses of :py:class:`Provider`). Providers
|
||||
will be called every time, when injection needs to be done. For example,
|
||||
if injectable value of injection is a ``di.Factory``, it will provide new one
|
||||
instance (as a result of its call) every time, when injection needs to be done.
|
||||
if injectable value of injection is a :py:class:`Factory`, it will provide
|
||||
new one instance (as a result of its call) every time, when injection needs
|
||||
to be done.
|
||||
|
||||
Example below is a little bit more complicated. It shows how to create
|
||||
``di.Factory`` of particular class with ``__init__()`` argument injections
|
||||
which injectable values are also provided by another factories:
|
||||
:py:class:`Factory` of particular class with ``__init__()`` argument
|
||||
injections which injectable values are also provided by another factories:
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -58,14 +62,14 @@ Example of usage keyword argument injections:
|
|||
Factory providers and __init__ injections priority
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Next example shows how ``di.Factory`` provider deals with positional and
|
||||
keyword ``__init__()`` context arguments. In few words, ``di.Factory``
|
||||
Next example shows how :py:class:`Factory` provider deals with positional and
|
||||
keyword ``__init__()`` context arguments. In few words, :py:class:`Factory`
|
||||
behaviour here is very like a standard Python ``functools.partial``:
|
||||
|
||||
- Positional context arguments will be appended after ``di.Factory``
|
||||
- Positional context arguments will be appended after :py:class:`Factory`
|
||||
positional injections.
|
||||
- Keyword context arguments have priority on ``di.Factory`` keyword injections
|
||||
and will be merged over them.
|
||||
- Keyword context arguments have priority on :py:class:`Factory` keyword
|
||||
injections and will be merged over them.
|
||||
|
||||
So, please, follow the example below:
|
||||
|
||||
|
@ -82,34 +86,38 @@ Objects can take dependencies in different forms (some objects take init
|
|||
arguments, other use attributes setting or method calls). It affects how
|
||||
such objects are created and initialized.
|
||||
|
||||
``di.Factory`` provider takes various number of positional and keyword
|
||||
:py:class:`Factory` provider takes various number of positional and keyword
|
||||
arguments, that define what kinds of dependency injections have to be used.
|
||||
|
||||
All of those instructions are defined in ``di.injections`` module and are
|
||||
subclasses of ``di.injections.Injection`` (shortcut ``di.Injection``). There
|
||||
are several types of injections that are used by ``di.Factory`` provider:
|
||||
All of those instructions are defined in
|
||||
:py:mod:`dependency_injector.injections` module and are subclasses of
|
||||
:py:class:`dependency_injector.injections.Injection`. There are several types
|
||||
of injections that are used by :py:class:`Factory` provider:
|
||||
|
||||
+ ``di.Arg`` - injection is done by passing injectable value in object's
|
||||
``__init__()`` method in time of object's creation as positional argument.
|
||||
Takes injectable value only.
|
||||
+ ``di.KwArg`` - injection is done by passing injectable value in object's
|
||||
``__init__()`` method in time of object's creation as keyword argument.
|
||||
Takes keyword name of ``__init__()`` argument and injectable value.
|
||||
+ ``di.Attribute`` - injection is done by setting specified attribute with
|
||||
injectable value right after object's creation. Takes attribute's name
|
||||
and injectable value.
|
||||
+ ``di.Method`` - injection is done by calling of specified method with
|
||||
injectable value right after object's creation and attribute injections
|
||||
are done. Takes method name and injectable value.
|
||||
+ :py:class:`dependency_injector.injections.Arg` - injection is done by
|
||||
passing injectable value in object's ``__init__()`` method in time of
|
||||
object's creation as positional argument. Takes injectable value only.
|
||||
+ :py:class:`dependency_injector.injections.KwArg` - injection is done by
|
||||
passing injectable value in object's ``__init__()`` method in time of
|
||||
object's creation as keyword argument. Takes keyword name of
|
||||
``__init__()`` argument and injectable value.
|
||||
+ :py:class:`dependency_injector.injections.Attribute` - injection is done
|
||||
by setting specified attribute with injectable value right after
|
||||
object's creation. Takes attribute's name and injectable value.
|
||||
+ :py:class:`dependency_injector.injections.Method` - injection is done by
|
||||
calling of specified method with injectable value right after object's
|
||||
creation and attribute injections are done. Takes method name and
|
||||
injectable value.
|
||||
|
||||
All ``di.Injection``'s injectable values are provided *"as is"*, except of
|
||||
providers (subclasses of ``di.Provider``). Providers will be called every time,
|
||||
when injection needs to be done.
|
||||
All :py:class:`dependency_injector.injections.Injection`'s injectable values
|
||||
are provided *"as is"*, except of providers (subclasses of
|
||||
:py:class:`Provider`). Providers will be called every time, when injection
|
||||
needs to be done.
|
||||
|
||||
Factory providers and attribute injections
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Example below shows how to create ``di.Factory`` of particular class with
|
||||
Example below shows how to create :py:class:`Factory` of particular class with
|
||||
attribute injections. Those injections are done by setting specified attributes
|
||||
with injectable values right after object's creation.
|
||||
|
||||
|
@ -123,10 +131,10 @@ Example:
|
|||
Factory providers and method injections
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Current example shows how to create ``di.Factory`` of particular class with
|
||||
method injections. Those injections are done by calling of specified method
|
||||
with injectable value right after object's creation and attribute injections
|
||||
are done.
|
||||
Current example shows how to create :py:class:`Factory` of particular class
|
||||
with method injections. Those injections are done by calling of specified
|
||||
method with injectable value right after object's creation and attribute
|
||||
injections are done.
|
||||
|
||||
Method injections are not very popular in Python due Python best practices
|
||||
(usage of public attributes instead of setter methods), but they may appear in
|
||||
|
@ -142,21 +150,21 @@ Example:
|
|||
Factory providers delegation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``di.Factory`` provider could be delegated to any other provider via any kind
|
||||
of injection. As it was mentioned earlier, if ``di.Factory`` is injectable
|
||||
value, it will be called every time when injection is done. ``di.Factory``
|
||||
delegation is performed by wrapping delegated ``di.Factory`` into special
|
||||
provider type - ``di.Delegate``, that just returns wrapped ``di.Factory``.
|
||||
Saying in other words, delegation of factories - is a way to inject factories
|
||||
themselves, instead of results of their calls.
|
||||
|
||||
:py:class:`Factory` provider could be delegated to any other provider via any
|
||||
kind of injection. As it was mentioned earlier, if :py:class:`Factory` is
|
||||
injectable value, it will be called every time when injection is done.
|
||||
:py:class:`Factory` delegation is performed by wrapping delegated
|
||||
:py:class:`Factory` into special provider type - :py:class:`Delegate`, that
|
||||
just returns wrapped :py:class:`Factory`. Saying in other words, delegation
|
||||
of factories - is a way to inject factories themselves, instead of results
|
||||
of their calls.
|
||||
|
||||
Actually, there are two ways of creating factory delegates:
|
||||
|
||||
+ ``di.Delegate(di.Factory(...))`` - obviously wrapping factory into
|
||||
``di.Delegate`` provider.
|
||||
+ ``di.Factory(...).delegate()`` - calling factory ``delegate()`` method, that
|
||||
returns delegate wrapper for current factory.
|
||||
+ ``Delegate(Factory(...))`` - obviously wrapping factory into
|
||||
:py:class:`Delegate` provider.
|
||||
+ ``Factory(...).delegate()`` - calling factory :py:meth:`Factory.delegate`
|
||||
method, that returns delegate wrapper for current factory.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
"""`di.Factory` providers example."""
|
||||
"""`Factory` providers example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
class User(object):
|
||||
"""Example class User."""
|
||||
|
||||
# Factory provider creates new instance of specified class on every call.
|
||||
users_factory = di.Factory(User)
|
||||
users_factory = providers.Factory(User)
|
||||
|
||||
# Creating several User objects:
|
||||
user1 = users_factory()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""`di.Factory` providers with attribute injections example."""
|
||||
"""`Factory` providers with attribute injections example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
from dependency_injector import injections
|
||||
|
||||
|
||||
class User(object):
|
||||
|
@ -20,11 +21,13 @@ class CreditCard(object):
|
|||
"""Example class CreditCard."""
|
||||
|
||||
# User, Photo and CreditCard factories:
|
||||
credit_cards_factory = di.Factory(CreditCard)
|
||||
photos_factory = di.Factory(Photo)
|
||||
users_factory = di.Factory(User,
|
||||
di.Attribute('main_photo', photos_factory),
|
||||
di.Attribute('credit_card', credit_cards_factory))
|
||||
credit_cards_factory = providers.Factory(CreditCard)
|
||||
photos_factory = providers.Factory(Photo)
|
||||
users_factory = providers.Factory(User,
|
||||
injections.Attribute('main_photo',
|
||||
photos_factory),
|
||||
injections.Attribute('credit_card',
|
||||
credit_cards_factory))
|
||||
|
||||
# Creating several User objects:
|
||||
user1 = users_factory()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""`di.Factory` providers delegation example."""
|
||||
"""`Factory` providers delegation example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
class User(object):
|
||||
|
@ -9,7 +9,7 @@ class User(object):
|
|||
def __init__(self, photos_factory):
|
||||
"""Initializer.
|
||||
|
||||
:param photos_factory: (di.Factory) -> Photo
|
||||
:param photos_factory: providers.Factory -> Photo
|
||||
"""
|
||||
self.photos_factory = photos_factory
|
||||
self._main_photo = None
|
||||
|
@ -27,9 +27,9 @@ class Photo(object):
|
|||
"""Example class Photo."""
|
||||
|
||||
# User and Photo factories:
|
||||
photos_factory = di.Factory(Photo)
|
||||
users_factory = di.Factory(User,
|
||||
photos_factory=di.Delegate(photos_factory))
|
||||
photos_factory = providers.Factory(Photo)
|
||||
users_factory = providers.Factory(User,
|
||||
photos_factory=photos_factory.delegate())
|
||||
|
||||
# Creating several User objects:
|
||||
user1 = users_factory()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""`di.Factory` providers with init positional injections example."""
|
||||
"""`Factory` providers with init positional injections example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
class User(object):
|
||||
|
@ -16,8 +16,8 @@ class Photo(object):
|
|||
"""Example class Photo."""
|
||||
|
||||
# User and Photo factories:
|
||||
photos_factory = di.Factory(Photo)
|
||||
users_factory = di.Factory(User, photos_factory)
|
||||
photos_factory = providers.Factory(Photo)
|
||||
users_factory = providers.Factory(User, photos_factory)
|
||||
|
||||
# Creating several User objects:
|
||||
user1 = users_factory() # Same as: user1 = User(Photo())
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""`di.Factory` providers with init injections priority example."""
|
||||
"""`Factory` providers with init injections priority example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
class User(object):
|
||||
|
@ -30,11 +30,11 @@ class CreditCard(object):
|
|||
"""Example class CreditCard."""
|
||||
|
||||
# User, Photo and CreditCard factories:
|
||||
credit_cards_factory = di.Factory(CreditCard)
|
||||
photos_factory = di.Factory(Photo)
|
||||
users_factory = di.Factory(User,
|
||||
main_photo=photos_factory,
|
||||
credit_card=credit_cards_factory)
|
||||
credit_cards_factory = providers.Factory(CreditCard)
|
||||
photos_factory = providers.Factory(Photo)
|
||||
users_factory = providers.Factory(User,
|
||||
main_photo=photos_factory,
|
||||
credit_card=credit_cards_factory)
|
||||
|
||||
# Creating several User objects:
|
||||
user1 = users_factory(1)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""`di.Factory` providers with init keyword injections example."""
|
||||
"""`Factory` providers with init keyword injections example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
class User(object):
|
||||
|
@ -16,8 +16,8 @@ class Photo(object):
|
|||
"""Example class Photo."""
|
||||
|
||||
# User and Photo factories:
|
||||
photos_factory = di.Factory(Photo)
|
||||
users_factory = di.Factory(User, main_photo=photos_factory)
|
||||
photos_factory = providers.Factory(Photo)
|
||||
users_factory = providers.Factory(User, main_photo=photos_factory)
|
||||
|
||||
# Creating several User objects:
|
||||
user1 = users_factory() # Same as: user1 = User(main_photo=Photo())
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""`di.Factory` providers with method injections example."""
|
||||
"""`Factory` providers with method injections example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
from dependency_injector import injections
|
||||
|
||||
|
||||
class User(object):
|
||||
|
@ -28,11 +29,13 @@ class CreditCard(object):
|
|||
"""Example class CreditCard."""
|
||||
|
||||
# User, Photo and CreditCard factories:
|
||||
credit_cards_factory = di.Factory(CreditCard)
|
||||
photos_factory = di.Factory(Photo)
|
||||
users_factory = di.Factory(User,
|
||||
di.Method('set_main_photo', photos_factory),
|
||||
di.Method('set_credit_card', credit_cards_factory))
|
||||
credit_cards_factory = providers.Factory(CreditCard)
|
||||
photos_factory = providers.Factory(Photo)
|
||||
users_factory = providers.Factory(User,
|
||||
injections.Method('set_main_photo',
|
||||
photos_factory),
|
||||
injections.Method('set_credit_card',
|
||||
credit_cards_factory))
|
||||
|
||||
# Creating several User objects:
|
||||
user1 = users_factory()
|
||||
|
|