mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-06-15 02:53:12 +03:00
Edit providers delegation section
This commit is contained in:
parent
1bd0abb897
commit
46935b3152
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
|
@ -77,48 +77,20 @@ If ``<dependency>`` is found the underlying provider will receive the
|
|||
|
||||
.. _factory_providers_delegation:
|
||||
|
||||
Factory providers delegation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Passing providers to the objects
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:py:class:`Factory` provider could be delegated to any other provider via any
|
||||
kind of injection.
|
||||
When you need to inject the provider itself, but not the result of its call, use the ``.provider``
|
||||
attribute of the provider that you're going to inject.
|
||||
|
||||
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`.
|
||||
|
||||
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`
|
||||
method, that returns delegate wrapper for current factory.
|
||||
+ ``Factory(...).provider`` - getting factory :py:attr:`Factory.provider`
|
||||
attribute, that returns delegate wrapper for current factory (alias of
|
||||
``Factory(...).delegate()`` method).
|
||||
|
||||
Example:
|
||||
|
||||
.. image:: /images/providers/factory_delegation.png
|
||||
:width: 85%
|
||||
:align: center
|
||||
.. image:: images/factory_delegation.png
|
||||
|
||||
.. literalinclude:: ../../examples/providers/factory_delegation.py
|
||||
:language: python
|
||||
:lines: 3-
|
||||
:emphasize-lines: 25
|
||||
|
||||
.. _factory_providers_specialization:
|
||||
.. note:: Any provider has a ``.provider`` attribute.
|
||||
|
||||
Factory providers specialization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
BIN
docs/providers/images/factory_delegation.png
Normal file
BIN
docs/providers/images/factory_delegation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -1,82 +1,37 @@
|
|||
"""`Factory` providers delegation example."""
|
||||
|
||||
import collections
|
||||
from typing import Callable, List
|
||||
|
||||
import dependency_injector.providers as providers
|
||||
|
||||
|
||||
Photo = collections.namedtuple('Photo', [])
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
class User:
|
||||
"""Example user model."""
|
||||
|
||||
def __init__(self, photos_factory):
|
||||
"""Initialize instance."""
|
||||
self.photos_factory = photos_factory
|
||||
self._main_photo = None
|
||||
|
||||
@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
|
||||
def __init__(self, uid: int) -> None:
|
||||
self.uid = uid
|
||||
|
||||
|
||||
# Defining User and Photo factories using DelegatedFactory provider:
|
||||
photos_factory = providers.DelegatedFactory(Photo)
|
||||
users_factory = providers.Factory(
|
||||
User,
|
||||
photos_factory=photos_factory,
|
||||
)
|
||||
class UserRepository:
|
||||
def __init__(self, user_factory: Callable[..., User]) -> None:
|
||||
self.user_factory = user_factory
|
||||
|
||||
# or using Delegate(Factory(...))
|
||||
def get_all(self) -> List[User]:
|
||||
return [
|
||||
self.user_factory(**user_data)
|
||||
for user_data in [{'uid': 1}, {'uid': 2}]
|
||||
]
|
||||
|
||||
photos_factory = providers.Factory(Photo)
|
||||
users_factory = providers.Factory(
|
||||
User,
|
||||
photos_factory=providers.Delegate(photos_factory),
|
||||
|
||||
user_factory = providers.Factory(User)
|
||||
user_repository_factory = providers.Factory(
|
||||
UserRepository,
|
||||
user_factory=user_factory.provider,
|
||||
)
|
||||
|
||||
|
||||
# or using Factory(...).delegate()
|
||||
if __name__ == '__main__':
|
||||
user_repository = user_repository_factory()
|
||||
|
||||
photos_factory = providers.Factory(Photo)
|
||||
users_factory = providers.Factory(
|
||||
User,
|
||||
photos_factory=photos_factory.delegate(),
|
||||
)
|
||||
user1, user2 = user_repository.get_all()
|
||||
|
||||
|
||||
# Creating several User objects:
|
||||
user1 = users_factory()
|
||||
user2 = users_factory()
|
||||
|
||||
# Same as:
|
||||
# user1 = User(photos_factory=photos_factory)
|
||||
# user2 = User(photos_factory=photos_factory)
|
||||
|
||||
# Making some asserts:
|
||||
assert isinstance(user1.main_photo, Photo)
|
||||
assert isinstance(user2.main_photo, Photo)
|
||||
|
||||
# or using Factory(...).provider
|
||||
|
||||
photos_factory = providers.Factory(Photo)
|
||||
users_factory = providers.Factory(
|
||||
User,
|
||||
photos_factory=photos_factory.provider,
|
||||
)
|
||||
|
||||
# Creating several User objects:
|
||||
user1 = users_factory()
|
||||
user2 = users_factory()
|
||||
|
||||
# Same as:
|
||||
# user1 = User(photos_factory=photos_factory)
|
||||
# user2 = User(photos_factory=photos_factory)
|
||||
|
||||
# Making some asserts:
|
||||
assert isinstance(user1.main_photo, Photo)
|
||||
assert isinstance(user2.main_photo, Photo)
|
||||
assert user1.uid == 1
|
||||
assert user2.uid == 2
|
||||
|
|
|
@ -8,8 +8,7 @@ class Photo:
|
|||
|
||||
|
||||
class User:
|
||||
|
||||
def __init__(self, uid: int, main_photo: Photo):
|
||||
def __init__(self, uid: int, main_photo: Photo) -> None:
|
||||
self.uid = uid
|
||||
self.main_photo = main_photo
|
||||
|
||||
|
|
|
@ -4,22 +4,22 @@ from dependency_injector import providers
|
|||
|
||||
|
||||
class Regularizer:
|
||||
def __init__(self, alpha: float):
|
||||
def __init__(self, alpha: float) -> None:
|
||||
self.alpha = alpha
|
||||
|
||||
|
||||
class Loss:
|
||||
def __init__(self, regularizer: Regularizer):
|
||||
def __init__(self, regularizer: Regularizer) -> None:
|
||||
self.regularizer = regularizer
|
||||
|
||||
|
||||
class ClassificationTask:
|
||||
def __init__(self, loss: Loss):
|
||||
def __init__(self, loss: Loss) -> None:
|
||||
self.loss = loss
|
||||
|
||||
|
||||
class Algorithm:
|
||||
def __init__(self, task: ClassificationTask):
|
||||
def __init__(self, task: ClassificationTask) -> None:
|
||||
self.task = task
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user