Edit FactoryAggregate docs

This commit is contained in:
Roman Mogylatov 2020-08-31 21:11:31 -04:00
parent 452c77cadd
commit a5320bc281
6 changed files with 83 additions and 101 deletions

View File

@ -123,35 +123,37 @@ provider with two peculiarities:
:lines: 3-
:emphasize-lines: 32
Factory aggregate providers
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Factory aggregate
~~~~~~~~~~~~~~~~~
:py:class:`FactoryAggregate` provider is a special type of provider that
aggregates other :py:class:`Factory` providers.
:py:class:`FactoryAggregate` provider aggregates multiple factories. When you call the
``FactoryAggregate`` it delegates the call to one of the factories.
The aggregated factories are associated with the string names. When you call the
``FactoryAggregate`` you have to provide one of the these names as a first argument.
``FactoryAggregate`` looks for the factory with a matching name and delegates it the work. The
rest of the arguments are passed to the delegated ``Factory``.
.. image:: images/factory_aggregate.png
:width: 100%
:align: center
.. literalinclude:: ../../examples/providers/factory_aggregate.py
:language: python
:lines: 3-
:emphasize-lines: 31-35,43
You can get a dictionary of the aggregated factories using the ``.factories`` attribute of the
``FactoryAggregate``. To get a game factories dictionary from the previous example you can use
``game_factory.factories`` attribute.
You can also access an aggregated factory as an attribute. To create the ``Chess`` object from the
previous example you can do ``chess = game_factory.chess('John', 'Jane')``.
.. note::
You can not override the ``FactoryAggregate`` provider.
:py:class:`FactoryAggregate` is not overridable. Calling of
:py:meth:`FactoryAggregate.override` will result in raising of an
exception.
Next prototype might be the best demonstration of
:py:class:`FactoryAggregate` features:
.. literalinclude:: ../../examples/providers/factory_aggregate/prototype.py
:language: python
Example below shows one of the :py:class:`FactoryAggregate` use cases, when
concrete implementation (game) must be selected based on dynamic input (CLI).
Listing of ``games.py``:
.. literalinclude:: ../../examples/providers/factory_aggregate/games.py
:language: python
Listing of ``example.py``:
.. literalinclude:: ../../examples/providers/factory_aggregate/example.py
:language: python
.. note::
When you inject the ``FactoryAggregate`` provider it is passed "as is".
.. disqus::

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,55 @@
"""`FactoryAggregate` provider example."""
import dataclasses
import sys
from dependency_injector import providers
@dataclasses.dataclass
class Game:
player1: str
player2: str
def play(self):
print(
f'{self.player1} and {self.player2} are '
f'playing {self.__class__.__name__.lower()}'
)
class Chess(Game):
...
class Checkers(Game):
...
class Ludo(Game):
...
game_factory = providers.FactoryAggregate(
chess=providers.Factory(Chess),
checkers=providers.Factory(Checkers),
ludo=providers.Factory(Ludo),
)
if __name__ == '__main__':
game_type = sys.argv[1].lower()
player1 = sys.argv[2].capitalize()
player2 = sys.argv[3].capitalize()
selected_game = game_factory(game_type, player1, player2)
selected_game.play()
# $ python factory_aggregate.py chess John Jane
# John and Jane are playing chess
#
# $ python factory_aggregate.py checkers John Jane
# John and Jane are playing checkers
#
# $ python factory_aggregate.py ludo John Jane
# John and Jane are playing ludo

View File

@ -1,31 +0,0 @@
"""`FactoryAggregate` providers example."""
import sys
import dependency_injector.providers as providers
from games import Chess, Checkers, Ludo
game_factory = providers.FactoryAggregate(
chess=providers.Factory(Chess),
checkers=providers.Factory(Checkers),
ludo=providers.Factory(Ludo),
)
if __name__ == '__main__':
game_type = sys.argv[1].lower()
player1 = sys.argv[2].capitalize()
player2 = sys.argv[3].capitalize()
selected_game = game_factory(game_type, player1, player2)
selected_game.play()
# $ python example.py chess John Jane
# John and Jane are playing chess
#
# $ python example.py checkers John Jane
# John and Jane are playing checkers
#
# $ python example.py ludo John Jane
# John and Jane are playing ludo

View File

@ -1,27 +0,0 @@
"""Example games module."""
class Game:
"""Base game class."""
def __init__(self, player1, player2):
"""Initialize instance."""
self.player1 = player1
self.player2 = player2
def play(self):
"""Play game."""
print('{0} and {1} are playing {2}'.format(
self.player1, self.player2, self.__class__.__name__.lower()))
class Chess(Game):
"""Chess game."""
class Checkers(Game):
"""Checkers game."""
class Ludo(Game):
"""Ludo game."""

View File

@ -1,17 +0,0 @@
"""FactoryAggregate provider prototype."""
class FactoryAggregate:
"""FactoryAggregate provider prototype."""
def __init__(self, **factories):
"""Initialize instance."""
self.factories = factories
def __call__(self, factory_name, *args, **kwargs):
"""Create object."""
return self.factories[factory_name](*args, **kwargs)
def __getattr__(self, factory_name):
"""Return factory with specified name."""
return self.factories[factory_name]