Update Factory provider docs and examples

This commit is contained in:
Roman Mogilatov 2015-11-21 23:59:36 +02:00
parent 556c842685
commit 7eed1cf880
16 changed files with 105 additions and 89 deletions

View File

@ -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 some init / shutdown functionality or something else, that deals with group
of providers. of providers.
Catalogs module API docs - :py:mod:`dependency_injector.catalogs`.
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -1,7 +1,10 @@
Factory providers 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: Nothing could be better than brief example:
@ -15,21 +18,22 @@ Nothing could be better than brief example:
Factory providers and __init__ injections Factory providers and __init__ injections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``di.Factory`` takes a various number of positional and keyword arguments that :py:class:`Factory` takes a various number of positional and keyword arguments
are used as ``__init__()`` injections. Every time, when ``di.Factory`` that are used as ``__init__()`` injections. Every time, when
creates new one instance, positional and keyword argument injections would be :py:class:`Factory` creates new one instance, positional and keyword
passed as an instance's arguments. argument injections would be passed as an instance's arguments.
Such behaviour is very similar to the standard Python ``functools.partial`` Such behaviour is very similar to the standard Python ``functools.partial``
object, except of one thing: all injectable values are provided 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, 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 if injectable value of injection is a :py:class:`Factory`, it will provide
instance (as a result of its call) every time, when injection needs to be done. 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 Example below is a little bit more complicated. It shows how to create
``di.Factory`` of particular class with ``__init__()`` argument injections :py:class:`Factory` of particular class with ``__init__()`` argument
which injectable values are also provided by another factories: injections which injectable values are also provided by another factories:
.. note:: .. note::
@ -58,14 +62,14 @@ Example of usage keyword argument injections:
Factory providers and __init__ injections priority Factory providers and __init__ injections priority
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Next example shows how ``di.Factory`` provider deals with positional and Next example shows how :py:class:`Factory` provider deals with positional and
keyword ``__init__()`` context arguments. In few words, ``di.Factory`` keyword ``__init__()`` context arguments. In few words, :py:class:`Factory`
behaviour here is very like a standard Python ``functools.partial``: 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. positional injections.
- Keyword context arguments have priority on ``di.Factory`` keyword injections - Keyword context arguments have priority on :py:class:`Factory` keyword
and will be merged over them. injections and will be merged over them.
So, please, follow the example below: 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 arguments, other use attributes setting or method calls). It affects how
such objects are created and initialized. 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. arguments, that define what kinds of dependency injections have to be used.
All of those instructions are defined in ``di.injections`` module and are All of those instructions are defined in
subclasses of ``di.injections.Injection`` (shortcut ``di.Injection``). There :py:mod:`dependency_injector.injections` module and are subclasses of
are several types of injections that are used by ``di.Factory`` provider: :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 + :py:class:`dependency_injector.injections.Arg` - injection is done by
``__init__()`` method in time of object's creation as positional argument. passing injectable value in object's ``__init__()`` method in time of
Takes injectable value only. object's creation as positional argument. Takes injectable value only.
+ ``di.KwArg`` - injection is done by passing injectable value in object's + :py:class:`dependency_injector.injections.KwArg` - injection is done by
``__init__()`` method in time of object's creation as keyword argument. passing injectable value in object's ``__init__()`` method in time of
Takes keyword name of ``__init__()`` argument and injectable value. object's creation as keyword argument. Takes keyword name of
+ ``di.Attribute`` - injection is done by setting specified attribute with ``__init__()`` argument and injectable value.
injectable value right after object's creation. Takes attribute's name + :py:class:`dependency_injector.injections.Attribute` - injection is done
and injectable value. by setting specified attribute with injectable value right after
+ ``di.Method`` - injection is done by calling of specified method with object's creation. Takes attribute's name and injectable value.
injectable value right after object's creation and attribute injections + :py:class:`dependency_injector.injections.Method` - injection is done by
are done. Takes method name and injectable value. 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 All :py:class:`dependency_injector.injections.Injection`'s injectable values
providers (subclasses of ``di.Provider``). Providers will be called every time, are provided *"as is"*, except of providers (subclasses of
when injection needs to be done. :py:class:`Provider`). Providers will be called every time, when injection
needs to be done.
Factory providers and attribute injections 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 attribute injections. Those injections are done by setting specified attributes
with injectable values right after object's creation. with injectable values right after object's creation.
@ -123,10 +131,10 @@ Example:
Factory providers and method injections Factory providers and method injections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Current example shows how to create ``di.Factory`` of particular class with Current example shows how to create :py:class:`Factory` of particular class
method injections. Those injections are done by calling of specified method with method injections. Those injections are done by calling of specified
with injectable value right after object's creation and attribute injections method with injectable value right after object's creation and attribute
are done. injections are done.
Method injections are not very popular in Python due Python best practices 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 (usage of public attributes instead of setter methods), but they may appear in
@ -142,21 +150,21 @@ Example:
Factory providers delegation Factory providers delegation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``di.Factory`` provider could be delegated to any other provider via any kind :py:class:`Factory` provider could be delegated to any other provider via any
of injection. As it was mentioned earlier, if ``di.Factory`` is injectable kind of injection. As it was mentioned earlier, if :py:class:`Factory` is
value, it will be called every time when injection is done. ``di.Factory`` injectable value, it will be called every time when injection is done.
delegation is performed by wrapping delegated ``di.Factory`` into special :py:class:`Factory` delegation is performed by wrapping delegated
provider type - ``di.Delegate``, that just returns wrapped ``di.Factory``. :py:class:`Factory` into special provider type - :py:class:`Delegate`, that
Saying in other words, delegation of factories - is a way to inject factories just returns wrapped :py:class:`Factory`. Saying in other words, delegation
themselves, instead of results of their calls. of factories - is a way to inject factories themselves, instead of results
of their calls.
Actually, there are two ways of creating factory delegates: Actually, there are two ways of creating factory delegates:
+ ``di.Delegate(di.Factory(...))`` - obviously wrapping factory into + ``Delegate(Factory(...))`` - obviously wrapping factory into
``di.Delegate`` provider. :py:class:`Delegate` provider.
+ ``di.Factory(...).delegate()`` - calling factory ``delegate()`` method, that + ``Factory(...).delegate()`` - calling factory :py:meth:`Factory.delegate`
returns delegate wrapper for current factory. method, that returns delegate wrapper for current factory.
Example: Example:

View File

@ -1,13 +1,13 @@
"""`di.Factory` providers example.""" """`Factory` providers example."""
import dependency_injector as di from dependency_injector import providers
class User(object): class User(object):
"""Example class User.""" """Example class User."""
# Factory provider creates new instance of specified class on every call. # 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: # Creating several User objects:
user1 = users_factory() user1 = users_factory()

View File

@ -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): class User(object):
@ -20,11 +21,13 @@ class CreditCard(object):
"""Example class CreditCard.""" """Example class CreditCard."""
# User, Photo and CreditCard factories: # User, Photo and CreditCard factories:
credit_cards_factory = di.Factory(CreditCard) credit_cards_factory = providers.Factory(CreditCard)
photos_factory = di.Factory(Photo) photos_factory = providers.Factory(Photo)
users_factory = di.Factory(User, users_factory = providers.Factory(User,
di.Attribute('main_photo', photos_factory), injections.Attribute('main_photo',
di.Attribute('credit_card', credit_cards_factory)) photos_factory),
injections.Attribute('credit_card',
credit_cards_factory))
# Creating several User objects: # Creating several User objects:
user1 = users_factory() user1 = users_factory()

View File

@ -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): class User(object):
@ -9,7 +9,7 @@ class User(object):
def __init__(self, photos_factory): def __init__(self, photos_factory):
"""Initializer. """Initializer.
:param photos_factory: (di.Factory) -> Photo :param photos_factory: providers.Factory -> Photo
""" """
self.photos_factory = photos_factory self.photos_factory = photos_factory
self._main_photo = None self._main_photo = None
@ -27,9 +27,9 @@ class Photo(object):
"""Example class Photo.""" """Example class Photo."""
# User and Photo factories: # User and Photo factories:
photos_factory = di.Factory(Photo) photos_factory = providers.Factory(Photo)
users_factory = di.Factory(User, users_factory = providers.Factory(User,
photos_factory=di.Delegate(photos_factory)) photos_factory=photos_factory.delegate())
# Creating several User objects: # Creating several User objects:
user1 = users_factory() user1 = users_factory()

View File

@ -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): class User(object):
@ -16,8 +16,8 @@ class Photo(object):
"""Example class Photo.""" """Example class Photo."""
# User and Photo factories: # User and Photo factories:
photos_factory = di.Factory(Photo) photos_factory = providers.Factory(Photo)
users_factory = di.Factory(User, photos_factory) users_factory = providers.Factory(User, photos_factory)
# Creating several User objects: # Creating several User objects:
user1 = users_factory() # Same as: user1 = User(Photo()) user1 = users_factory() # Same as: user1 = User(Photo())

View File

@ -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): class User(object):
@ -30,11 +30,11 @@ class CreditCard(object):
"""Example class CreditCard.""" """Example class CreditCard."""
# User, Photo and CreditCard factories: # User, Photo and CreditCard factories:
credit_cards_factory = di.Factory(CreditCard) credit_cards_factory = providers.Factory(CreditCard)
photos_factory = di.Factory(Photo) photos_factory = providers.Factory(Photo)
users_factory = di.Factory(User, users_factory = providers.Factory(User,
main_photo=photos_factory, main_photo=photos_factory,
credit_card=credit_cards_factory) credit_card=credit_cards_factory)
# Creating several User objects: # Creating several User objects:
user1 = users_factory(1) user1 = users_factory(1)

View File

@ -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): class User(object):
@ -16,8 +16,8 @@ class Photo(object):
"""Example class Photo.""" """Example class Photo."""
# User and Photo factories: # User and Photo factories:
photos_factory = di.Factory(Photo) photos_factory = providers.Factory(Photo)
users_factory = di.Factory(User, main_photo=photos_factory) users_factory = providers.Factory(User, main_photo=photos_factory)
# Creating several User objects: # Creating several User objects:
user1 = users_factory() # Same as: user1 = User(main_photo=Photo()) user1 = users_factory() # Same as: user1 = User(main_photo=Photo())

View File

@ -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): class User(object):
@ -28,11 +29,13 @@ class CreditCard(object):
"""Example class CreditCard.""" """Example class CreditCard."""
# User, Photo and CreditCard factories: # User, Photo and CreditCard factories:
credit_cards_factory = di.Factory(CreditCard) credit_cards_factory = providers.Factory(CreditCard)
photos_factory = di.Factory(Photo) photos_factory = providers.Factory(Photo)
users_factory = di.Factory(User, users_factory = providers.Factory(User,
di.Method('set_main_photo', photos_factory), injections.Method('set_main_photo',
di.Method('set_credit_card', credit_cards_factory)) photos_factory),
injections.Method('set_credit_card',
credit_cards_factory))
# Creating several User objects: # Creating several User objects:
user1 = users_factory() user1 = users_factory()