mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 01:47:36 +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