Update factory provider docs
| 
		 Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 9.2 KiB  | 
| 
		 Before Width: | Height: | Size: 66 KiB  | 
| 
		 Before Width: | Height: | Size: 66 KiB  | 
| 
		 Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 22 KiB  | 
| 
		 Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 32 KiB  | 
| 
		 Before Width: | Height: | Size: 68 KiB  | 
| 
		 Before Width: | Height: | Size: 72 KiB  | 
| 
						 | 
				
			
			@ -24,137 +24,29 @@ 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 with several more things: 
 | 
			
		||||
Injections are done according to the next rules:
 | 
			
		||||
 | 
			
		||||
+ All providers (instances of :py:class:`Provider`) are called every time 
 | 
			
		||||
  when injection needs to be done.
 | 
			
		||||
+ Providers could be injected "as is" (delegated), if it is defined obviously.
 | 
			
		||||
  Check out `Factory providers delegation`_.
 | 
			
		||||
+ All other injectable values are provided *"as is"*
 | 
			
		||||
  
 | 
			
		||||
+ All other injectable values are provided *"as is"*.
 | 
			
		||||
+ Positional context arguments will be appended after :py:class:`Factory` 
 | 
			
		||||
  positional injections.
 | 
			
		||||
+ Keyword context arguments have priority on :py:class:`Factory` keyword 
 | 
			
		||||
  injections and will be merged over them.
 | 
			
		||||
 | 
			
		||||
For example, 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 
 | 
			
		||||
:py:class:`Factory` of particular class with ``__init__()`` argument 
 | 
			
		||||
injections which injectable values are also provided by another factories:
 | 
			
		||||
 | 
			
		||||
.. note:: 
 | 
			
		||||
 | 
			
		||||
    Current positional and keyword argument injections syntax (in the examples
 | 
			
		||||
    below) is a **simplified one** version of full syntax. Examples of full 
 | 
			
		||||
    syntax and other types of injections could be found in sections below.
 | 
			
		||||
 | 
			
		||||
    While positional / keyword argument injections may be the best way of 
 | 
			
		||||
    passing injections, current simplified syntax might be the preferable one 
 | 
			
		||||
    and could be widely used.
 | 
			
		||||
:py:class:`Factory` of particular class with ``__init__()`` injections which 
 | 
			
		||||
injectable values are also provided by another factories:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/providers/factory_init_injections.png
 | 
			
		||||
    :width: 90%
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
Example of usage positional argument injections:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/factory_init_args.py
 | 
			
		||||
   :language: python
 | 
			
		||||
   :linenos:
 | 
			
		||||
 | 
			
		||||
Example of usage keyword argument injections:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/factory_init_kwargs.py
 | 
			
		||||
   :language: python
 | 
			
		||||
   :linenos:
 | 
			
		||||
 | 
			
		||||
Factory providers and __init__ injections priority
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
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 :py:class:`Factory` 
 | 
			
		||||
  positional injections.
 | 
			
		||||
- Keyword context arguments have priority on :py:class:`Factory` keyword 
 | 
			
		||||
  injections and will be merged over them.
 | 
			
		||||
 | 
			
		||||
So, please, follow the example below:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/providers/factory_init_injections_and_contexts.png
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/factory_init_injections_and_contexts.py
 | 
			
		||||
   :language: python
 | 
			
		||||
   :linenos:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Factory providers and other types of injections
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
: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 
 | 
			
		||||
: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:
 | 
			
		||||
 | 
			
		||||
+ :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 :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 :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.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/providers/factory_attribute_injections.png
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/factory_attribute_injections.py
 | 
			
		||||
   :language: python
 | 
			
		||||
   :linenos:
 | 
			
		||||
 | 
			
		||||
Factory providers and method injections
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
some cases.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/providers/factory_method_injections.png
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/factory_method_injections.py
 | 
			
		||||
.. literalinclude:: ../../examples/providers/factory_init_injections.py
 | 
			
		||||
   :language: python
 | 
			
		||||
   :linenos:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -162,16 +54,26 @@ Factory providers delegation
 | 
			
		|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
: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. 
 | 
			
		||||
kind of injection. 
 | 
			
		||||
 | 
			
		||||
As it was mentioned earlier, if :py:class:`Factory` is 
 | 
			
		||||
injectable value, it will be called every time when injection needs to be 
 | 
			
		||||
done. But sometimes there is a need to inject :py:class:`Factory` provider 
 | 
			
		||||
itself (not a result of its call) as a dependency. Such injections are called 
 | 
			
		||||
- *delegated provider injections*.
 | 
			
		||||
  
 | 
			
		||||
Saying in other words, delegation of factories - is a way to inject factories 
 | 
			
		||||
themselves, instead of results of their calls. 
 | 
			
		||||
 | 
			
		||||
: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. 
 | 
			
		||||
just returns wrapped :py:class:`Factory`. 
 | 
			
		||||
 | 
			
		||||
Actually, there are two ways of creating factory delegates:
 | 
			
		||||
Actually, there are three ways for creating factory delegates:
 | 
			
		||||
 | 
			
		||||
+ ``DelegatedFactory(...)`` - use special type of factory - 
 | 
			
		||||
  :py:class:`DelegatedFactory`. Such factories are always injected as 
 | 
			
		||||
  delegates ("as is"). 
 | 
			
		||||
+ ``Delegate(Factory(...))`` - obviously wrapping factory into 
 | 
			
		||||
  :py:class:`Delegate` provider.
 | 
			
		||||
+ ``Factory(...).delegate()`` - calling factory :py:meth:`Factory.delegate` 
 | 
			
		||||
| 
						 | 
				
			
			@ -187,24 +89,14 @@ Example:
 | 
			
		|||
   :language: python
 | 
			
		||||
   :linenos:
 | 
			
		||||
 | 
			
		||||
Alternative way of doing :py:class:`Factory` delegation is an usage of 
 | 
			
		||||
:py:class:`DelegatedFactory`. :py:class:`DelegatedFactory` is a 
 | 
			
		||||
:py:class:`Factory` that is always injected "as is".
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/delegated_factory.py
 | 
			
		||||
   :language: python
 | 
			
		||||
   :linenos:
 | 
			
		||||
 | 
			
		||||
Factory providers specialization
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
:py:class:`Factory` provider could be specialized for any kind of needs via 
 | 
			
		||||
declaring its subclasses. 
 | 
			
		||||
creating its subclasses. 
 | 
			
		||||
 | 
			
		||||
One of such `builtin` features is a limitation to :py:class:`Factory` provided 
 | 
			
		||||
type:
 | 
			
		||||
One of such specialization features is a limitation to :py:class:`Factory` 
 | 
			
		||||
provided type:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/factory_provided_type.py
 | 
			
		||||
   :language: python
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
Providers
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
Providers are strategies of accessing objects. They describe how particular 
 | 
			
		||||
Providers are strategies of accessing objects. They define how particular 
 | 
			
		||||
objects are provided.
 | 
			
		||||
 | 
			
		||||
Base providers class is - :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,46 +0,0 @@
 | 
			
		|||
"""`DelegatedFactory` providers example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector.providers as providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User."""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, photos_factory):
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param photos_factory: providers.Factory -> Photo
 | 
			
		||||
        """
 | 
			
		||||
        self.photos_factory = photos_factory
 | 
			
		||||
        self._main_photo = None
 | 
			
		||||
        super(User, self).__init__()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def main_photo(self):
 | 
			
		||||
        """Return user's main photo."""
 | 
			
		||||
        if not self._main_photo:
 | 
			
		||||
            self._main_photo = self.photos_factory()
 | 
			
		||||
        return self._main_photo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Photo(object):
 | 
			
		||||
    """Example class Photo."""
 | 
			
		||||
 | 
			
		||||
# User and Photo factories:
 | 
			
		||||
photos_factory = providers.DelegatedFactory(Photo)
 | 
			
		||||
users_factory = providers.DelegatedFactory(User,
 | 
			
		||||
                                           photos_factory=photos_factory)
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()
 | 
			
		||||
user2 = users_factory()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert isinstance(user1, User)
 | 
			
		||||
assert isinstance(user1.main_photo, Photo)
 | 
			
		||||
 | 
			
		||||
assert isinstance(user2, User)
 | 
			
		||||
assert isinstance(user2.main_photo, Photo)
 | 
			
		||||
 | 
			
		||||
assert user1 is not user2
 | 
			
		||||
assert user1.main_photo is not user2.main_photo
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +1,14 @@
 | 
			
		|||
"""`Factory` providers example."""
 | 
			
		||||
 | 
			
		||||
import collections
 | 
			
		||||
import dependency_injector.providers as providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User."""
 | 
			
		||||
User = collections.namedtuple('User', [])
 | 
			
		||||
 | 
			
		||||
# Factory provider creates new instance of specified class on every call.
 | 
			
		||||
users_factory = providers.Factory(User)
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()
 | 
			
		||||
user2 = users_factory()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert user1 is not user2
 | 
			
		||||
assert isinstance(user1, User) and isinstance(user2, User)
 | 
			
		||||
user1 = users_factory()  # Same as: user1 = User()
 | 
			
		||||
user2 = users_factory()  # Same as: user2 = User()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,52 +0,0 @@
 | 
			
		|||
"""`Factory` providers with attribute injections example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector.providers as providers
 | 
			
		||||
import dependency_injector.injections as injections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User."""
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self.main_photo = None
 | 
			
		||||
        self.credit_card = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Photo(object):
 | 
			
		||||
    """Example class Photo."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreditCard(object):
 | 
			
		||||
    """Example class CreditCard."""
 | 
			
		||||
 | 
			
		||||
# User, Photo and CreditCard factories:
 | 
			
		||||
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()
 | 
			
		||||
# Same as: user1 = User()
 | 
			
		||||
#          user1.main_photo = Photo()
 | 
			
		||||
#          user1.credit_card = CreditCard()
 | 
			
		||||
user2 = users_factory()
 | 
			
		||||
# Same as: user2 = User()
 | 
			
		||||
#          user2.main_photo = Photo()
 | 
			
		||||
#          user2.credit_card = CreditCard()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert user1 is not user2
 | 
			
		||||
 | 
			
		||||
assert isinstance(user1.main_photo, Photo)
 | 
			
		||||
assert isinstance(user1.credit_card, CreditCard)
 | 
			
		||||
 | 
			
		||||
assert isinstance(user2.main_photo, Photo)
 | 
			
		||||
assert isinstance(user2.credit_card, CreditCard)
 | 
			
		||||
 | 
			
		||||
assert user1.main_photo is not user2.main_photo
 | 
			
		||||
assert user1.credit_card is not user2.credit_card
 | 
			
		||||
| 
						 | 
				
			
			@ -1,19 +1,19 @@
 | 
			
		|||
"""`Factory` providers delegation example."""
 | 
			
		||||
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
import collections
 | 
			
		||||
import dependency_injector.providers as providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Photo = collections.namedtuple('Photo', [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User."""
 | 
			
		||||
    """Example user model."""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, photos_factory):
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param photos_factory: providers.Factory -> Photo
 | 
			
		||||
        """
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self.photos_factory = photos_factory
 | 
			
		||||
        self._main_photo = None
 | 
			
		||||
        super(User, self).__init__()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def main_photo(self):
 | 
			
		||||
| 
						 | 
				
			
			@ -23,24 +23,30 @@ class User(object):
 | 
			
		|||
        return self._main_photo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Photo(object):
 | 
			
		||||
    """Example class Photo."""
 | 
			
		||||
# Defining User and Photo factories using DelegatedFactory provider:
 | 
			
		||||
photos_factory = providers.DelegatedFactory(Photo)
 | 
			
		||||
users_factory = providers.DelegatedFactory(User,
 | 
			
		||||
                                           photos_factory=photos_factory)
 | 
			
		||||
 | 
			
		||||
# or using Delegate(Factory(...))
 | 
			
		||||
 | 
			
		||||
photos_factory = providers.Factory(Photo)
 | 
			
		||||
users_factory = providers.Factory(User,
 | 
			
		||||
                                  photos_factory=providers.Delegate(
 | 
			
		||||
                                      photos_factory))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# or using Factory(...).delegate()
 | 
			
		||||
 | 
			
		||||
# User and Photo factories:
 | 
			
		||||
photos_factory = providers.Factory(Photo)
 | 
			
		||||
users_factory = providers.Factory(User,
 | 
			
		||||
                                  photos_factory=photos_factory.delegate())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()
 | 
			
		||||
user2 = users_factory()
 | 
			
		||||
user1 = users_factory()  # Same as: user1 = User(photos_factory=photos_factory)
 | 
			
		||||
user2 = users_factory()  # Same as: user2 = User(photos_factory=photos_factory)
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert isinstance(user1, User)
 | 
			
		||||
assert isinstance(user1.main_photo, Photo)
 | 
			
		||||
 | 
			
		||||
assert isinstance(user2, User)
 | 
			
		||||
assert isinstance(user2.main_photo, Photo)
 | 
			
		||||
 | 
			
		||||
assert user1 is not user2
 | 
			
		||||
assert user1.main_photo is not user2.main_photo
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,34 +0,0 @@
 | 
			
		|||
"""`Factory` providers with init positional injections example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector.providers as providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User."""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, main_photo):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self.main_photo = main_photo
 | 
			
		||||
        super(User, self).__init__()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Photo(object):
 | 
			
		||||
    """Example class Photo."""
 | 
			
		||||
 | 
			
		||||
# User and Photo factories:
 | 
			
		||||
photos_factory = providers.Factory(Photo)
 | 
			
		||||
users_factory = providers.Factory(User, photos_factory)
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()  # Same as: user1 = User(Photo())
 | 
			
		||||
user2 = users_factory()  # Same as: user2 = User(Photo())
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert isinstance(user1, User)
 | 
			
		||||
assert isinstance(user1.main_photo, Photo)
 | 
			
		||||
 | 
			
		||||
assert isinstance(user2, User)
 | 
			
		||||
assert isinstance(user2.main_photo, Photo)
 | 
			
		||||
 | 
			
		||||
assert user1 is not user2
 | 
			
		||||
assert user1.main_photo is not user2.main_photo
 | 
			
		||||
							
								
								
									
										38
									
								
								examples/providers/factory_init_injections.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
"""`Factory` providers init injections example."""
 | 
			
		||||
 | 
			
		||||
import collections
 | 
			
		||||
import dependency_injector.providers as providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CreditCard = collections.namedtuple('CreditCard', [])
 | 
			
		||||
Photo = collections.namedtuple('Photo', [])
 | 
			
		||||
User = collections.namedtuple('User', ['uid', 'main_photo', 'credit_card'])
 | 
			
		||||
 | 
			
		||||
# User, Photo and CreditCard factories:
 | 
			
		||||
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)
 | 
			
		||||
# Same as: user1 = User(1,
 | 
			
		||||
#                       main_photo=Photo(),
 | 
			
		||||
#                       credit_card=CreditCard())
 | 
			
		||||
user2 = users_factory(2)
 | 
			
		||||
# Same as: user2 = User(2,
 | 
			
		||||
#                       main_photo=Photo(),
 | 
			
		||||
#                       credit_card=CreditCard())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Context keyword arguments have priority on keyword argument injections:
 | 
			
		||||
main_photo = Photo()
 | 
			
		||||
credit_card = CreditCard()
 | 
			
		||||
 | 
			
		||||
user3 = users_factory(3,
 | 
			
		||||
                      main_photo=main_photo,
 | 
			
		||||
                      credit_card=credit_card)
 | 
			
		||||
# Same as: user3 = User(3,
 | 
			
		||||
#                       main_photo=main_photo,
 | 
			
		||||
#                       credit_card=credit_card)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,71 +0,0 @@
 | 
			
		|||
"""`Factory` providers with init injections priority example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector.providers as providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User.
 | 
			
		||||
 | 
			
		||||
    Class User has to be provided with user id.
 | 
			
		||||
 | 
			
		||||
    Also Class User has dependencies on class Photo and class CreditCard
 | 
			
		||||
    objects.
 | 
			
		||||
 | 
			
		||||
    All of the dependencies have to be provided like __init__ arguments.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, id, main_photo, credit_card):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self.id = id
 | 
			
		||||
        self.main_photo = main_photo
 | 
			
		||||
        self.credit_card = credit_card
 | 
			
		||||
        super(User, self).__init__()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Photo(object):
 | 
			
		||||
    """Example class Photo."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreditCard(object):
 | 
			
		||||
    """Example class CreditCard."""
 | 
			
		||||
 | 
			
		||||
# User, Photo and CreditCard factories:
 | 
			
		||||
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)
 | 
			
		||||
# Same as: user1 = User(1,
 | 
			
		||||
#                       main_photo=Photo(),
 | 
			
		||||
#                       credit_card=CreditCard())
 | 
			
		||||
user2 = users_factory(2)
 | 
			
		||||
# Same as: user2 = User(2,
 | 
			
		||||
#                       main_photo=Photo(),
 | 
			
		||||
#                       credit_card=CreditCard())
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert user1.id == 1
 | 
			
		||||
assert isinstance(user1.main_photo, Photo)
 | 
			
		||||
assert isinstance(user1.credit_card, CreditCard)
 | 
			
		||||
 | 
			
		||||
assert user2.id == 2
 | 
			
		||||
assert isinstance(user2.main_photo, Photo)
 | 
			
		||||
assert isinstance(user2.credit_card, CreditCard)
 | 
			
		||||
 | 
			
		||||
assert user1.main_photo is not user2.main_photo
 | 
			
		||||
assert user1.credit_card is not user2.credit_card
 | 
			
		||||
 | 
			
		||||
# Context keyword arguments have priority on keyword argument injections:
 | 
			
		||||
main_photo_mock = Photo()
 | 
			
		||||
credit_card_mock = CreditCard()
 | 
			
		||||
 | 
			
		||||
user3 = users_factory(3,
 | 
			
		||||
                      main_photo=main_photo_mock,
 | 
			
		||||
                      credit_card=credit_card_mock)
 | 
			
		||||
 | 
			
		||||
assert user3.id == 3
 | 
			
		||||
assert user3.main_photo is main_photo_mock
 | 
			
		||||
assert user3.credit_card is credit_card_mock
 | 
			
		||||
| 
						 | 
				
			
			@ -1,34 +0,0 @@
 | 
			
		|||
"""`Factory` providers with init keyword injections example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector.providers as providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User."""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, main_photo):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self.main_photo = main_photo
 | 
			
		||||
        super(User, self).__init__()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Photo(object):
 | 
			
		||||
    """Example class Photo."""
 | 
			
		||||
 | 
			
		||||
# User and Photo factories:
 | 
			
		||||
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())
 | 
			
		||||
user2 = users_factory()  # Same as: user2 = User(main_photo=Photo())
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert isinstance(user1, User)
 | 
			
		||||
assert isinstance(user1.main_photo, Photo)
 | 
			
		||||
 | 
			
		||||
assert isinstance(user2, User)
 | 
			
		||||
assert isinstance(user2.main_photo, Photo)
 | 
			
		||||
 | 
			
		||||
assert user1 is not user2
 | 
			
		||||
assert user1.main_photo is not user2.main_photo
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
"""`Factory` specialization for limitation to provided type example."""
 | 
			
		||||
"""`Factory` specialization with limitation to provided type example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector.providers as providers
 | 
			
		||||
import dependency_injector.errors as errors
 | 
			
		||||
| 
						 | 
				
			
			@ -8,12 +8,8 @@ class BaseService(object):
 | 
			
		|||
    """Base service class."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UsersService(BaseService):
 | 
			
		||||
    """Users service."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PhotosService(BaseService):
 | 
			
		||||
    """Photos service."""
 | 
			
		||||
class SomeService(BaseService):
 | 
			
		||||
    """Some service."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ServiceProvider(providers.Factory):
 | 
			
		||||
| 
						 | 
				
			
			@ -22,11 +18,10 @@ class ServiceProvider(providers.Factory):
 | 
			
		|||
    provided_type = BaseService
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating several service providers with BaseService instances:
 | 
			
		||||
users_service_provider = ServiceProvider(UsersService)
 | 
			
		||||
photos_service_provider = ServiceProvider(PhotosService)
 | 
			
		||||
# Creating service provider with correct provided type:
 | 
			
		||||
some_service_provider = ServiceProvider(SomeService)
 | 
			
		||||
 | 
			
		||||
# Trying to create service provider with not a BaseService instance:
 | 
			
		||||
# Trying to create service provider incorrect provided type:
 | 
			
		||||
try:
 | 
			
		||||
    some_service_provider = ServiceProvider(object)
 | 
			
		||||
except errors.Error as exception:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||