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
|
:py:class:`Factory` creates new one instance, positional and keyword
|
||||||
argument injections would be 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``
|
Injections are done according to the next rules:
|
||||||
object with several more things:
|
|
||||||
|
|
||||||
+ All providers (instances of :py:class:`Provider`) are called every time
|
+ All providers (instances of :py:class:`Provider`) are called every time
|
||||||
when injection needs to be done.
|
when injection needs to be done.
|
||||||
+ Providers could be injected "as is" (delegated), if it is defined obviously.
|
+ Providers could be injected "as is" (delegated), if it is defined obviously.
|
||||||
Check out `Factory providers delegation`_.
|
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
|
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
|
will provide new one instance (as a result of its call) every time, when
|
||||||
injection needs to be done.
|
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
|
||||||
:py:class:`Factory` of particular class with ``__init__()`` argument
|
:py:class:`Factory` of particular class with ``__init__()`` injections which
|
||||||
injections which injectable values are also provided by another factories:
|
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.
|
|
||||||
|
|
||||||
.. image:: /images/providers/factory_init_injections.png
|
.. image:: /images/providers/factory_init_injections.png
|
||||||
:width: 90%
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
Example of usage positional argument injections:
|
.. literalinclude:: ../../examples/providers/factory_init_injections.py
|
||||||
|
|
||||||
.. 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
|
|
||||||
:language: python
|
:language: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
|
@ -162,16 +54,26 @@ Factory providers delegation
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
:py:class:`Factory` provider could be delegated to any other provider via any
|
: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
|
kind of injection.
|
||||||
injectable value, it will be called every time when injection is done.
|
|
||||||
|
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` delegation is performed by wrapping delegated
|
||||||
:py:class:`Factory` into special provider type - :py:class:`Delegate`, that
|
:py:class:`Factory` into special provider type - :py:class:`Delegate`, that
|
||||||
just returns wrapped :py:class:`Factory`. Saying in other words, delegation
|
just returns wrapped :py:class:`Factory`.
|
||||||
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 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
|
+ ``Delegate(Factory(...))`` - obviously wrapping factory into
|
||||||
:py:class:`Delegate` provider.
|
:py:class:`Delegate` provider.
|
||||||
+ ``Factory(...).delegate()`` - calling factory :py:meth:`Factory.delegate`
|
+ ``Factory(...).delegate()`` - calling factory :py:meth:`Factory.delegate`
|
||||||
|
@ -187,24 +89,14 @@ Example:
|
||||||
:language: python
|
:language: python
|
||||||
:linenos:
|
: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
|
Factory providers specialization
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
:py:class:`Factory` provider could be specialized for any kind of needs via
|
: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
|
One of such specialization features is a limitation to :py:class:`Factory`
|
||||||
type:
|
provided type:
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/providers/factory_provided_type.py
|
.. literalinclude:: ../../examples/providers/factory_provided_type.py
|
||||||
:language: python
|
:language: python
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Providers
|
Providers
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Providers are strategies of accessing objects. They describe how particular
|
Providers are strategies of accessing objects. They define how particular
|
||||||
objects are provided.
|
objects are provided.
|
||||||
|
|
||||||
Base providers class is - :py:class:`dependency_injector.providers.Provider`
|
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."""
|
"""`Factory` providers example."""
|
||||||
|
|
||||||
|
import collections
|
||||||
import dependency_injector.providers as providers
|
import dependency_injector.providers as providers
|
||||||
|
|
||||||
|
|
||||||
class User(object):
|
User = collections.namedtuple('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 = providers.Factory(User)
|
users_factory = providers.Factory(User)
|
||||||
|
|
||||||
# Creating several User objects:
|
# Creating several User objects:
|
||||||
user1 = users_factory()
|
user1 = users_factory() # Same as: user1 = User()
|
||||||
user2 = users_factory()
|
user2 = users_factory() # Same as: user2 = User()
|
||||||
|
|
||||||
# Making some asserts:
|
|
||||||
assert user1 is not user2
|
|
||||||
assert isinstance(user1, User) and isinstance(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."""
|
"""`Factory` providers delegation example."""
|
||||||
|
|
||||||
from dependency_injector import providers
|
import collections
|
||||||
|
import dependency_injector.providers as providers
|
||||||
|
|
||||||
|
|
||||||
|
Photo = collections.namedtuple('Photo', [])
|
||||||
|
|
||||||
|
|
||||||
class User(object):
|
class User(object):
|
||||||
"""Example class User."""
|
"""Example user model."""
|
||||||
|
|
||||||
def __init__(self, photos_factory):
|
def __init__(self, photos_factory):
|
||||||
"""Initializer.
|
"""Initializer."""
|
||||||
|
|
||||||
:param photos_factory: providers.Factory -> Photo
|
|
||||||
"""
|
|
||||||
self.photos_factory = photos_factory
|
self.photos_factory = photos_factory
|
||||||
self._main_photo = None
|
self._main_photo = None
|
||||||
super(User, self).__init__()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def main_photo(self):
|
def main_photo(self):
|
||||||
|
@ -23,24 +23,30 @@ class User(object):
|
||||||
return self._main_photo
|
return self._main_photo
|
||||||
|
|
||||||
|
|
||||||
class Photo(object):
|
# Defining User and Photo factories using DelegatedFactory provider:
|
||||||
"""Example class Photo."""
|
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)
|
photos_factory = providers.Factory(Photo)
|
||||||
users_factory = providers.Factory(User,
|
users_factory = providers.Factory(User,
|
||||||
photos_factory=photos_factory.delegate())
|
photos_factory=photos_factory.delegate())
|
||||||
|
|
||||||
|
|
||||||
# Creating several User objects:
|
# Creating several User objects:
|
||||||
user1 = users_factory()
|
user1 = users_factory() # Same as: user1 = User(photos_factory=photos_factory)
|
||||||
user2 = users_factory()
|
user2 = users_factory() # Same as: user2 = User(photos_factory=photos_factory)
|
||||||
|
|
||||||
# Making some asserts:
|
# Making some asserts:
|
||||||
assert isinstance(user1, User)
|
|
||||||
assert isinstance(user1.main_photo, Photo)
|
assert isinstance(user1.main_photo, Photo)
|
||||||
|
|
||||||
assert isinstance(user2, User)
|
|
||||||
assert isinstance(user2.main_photo, Photo)
|
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.providers as providers
|
||||||
import dependency_injector.errors as errors
|
import dependency_injector.errors as errors
|
||||||
|
@ -8,12 +8,8 @@ class BaseService(object):
|
||||||
"""Base service class."""
|
"""Base service class."""
|
||||||
|
|
||||||
|
|
||||||
class UsersService(BaseService):
|
class SomeService(BaseService):
|
||||||
"""Users service."""
|
"""Some service."""
|
||||||
|
|
||||||
|
|
||||||
class PhotosService(BaseService):
|
|
||||||
"""Photos service."""
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceProvider(providers.Factory):
|
class ServiceProvider(providers.Factory):
|
||||||
|
@ -22,11 +18,10 @@ class ServiceProvider(providers.Factory):
|
||||||
provided_type = BaseService
|
provided_type = BaseService
|
||||||
|
|
||||||
|
|
||||||
# Creating several service providers with BaseService instances:
|
# Creating service provider with correct provided type:
|
||||||
users_service_provider = ServiceProvider(UsersService)
|
some_service_provider = ServiceProvider(SomeService)
|
||||||
photos_service_provider = ServiceProvider(PhotosService)
|
|
||||||
|
|
||||||
# Trying to create service provider with not a BaseService instance:
|
# Trying to create service provider incorrect provided type:
|
||||||
try:
|
try:
|
||||||
some_service_provider = ServiceProvider(object)
|
some_service_provider = ServiceProvider(object)
|
||||||
except errors.Error as exception:
|
except errors.Error as exception:
|
||||||
|
|