Skip to content

Commit

Permalink
Merge pull request #174 from ets-labs/feature/factory-aggregate
Browse files Browse the repository at this point in the history
Create FactoryAggregate provider
  • Loading branch information
rmk135 committed Oct 13, 2017
2 parents 2808ae1 + 3364d6f commit 9305b9d
Show file tree
Hide file tree
Showing 13 changed files with 6,737 additions and 4,232 deletions.
3 changes: 2 additions & 1 deletion docs/main/changelog.rst
Expand Up @@ -9,8 +9,9 @@ follows `Semantic versioning`_

Development version
-------------------
- Add ``FactoryAggregate`` provider.
- Add support of six 1.11.0.
- Regenerate C sources using Cython 0.27.
- Regenerate C sources using Cython 0.27.1.

3.6.1
-----
Expand Down
34 changes: 34 additions & 0 deletions docs/providers/factory.rst
Expand Up @@ -147,4 +147,38 @@ Listing of ``example.py``:
:language: python
:linenos:

Factory aggregate providers
~~~~~~~~~~~~~~~~~~~~~~~~~~~

:py:class:`FactoryAggregate` provider is a special type of provider that
aggregates other :py:class:`Factory` providers.

.. note::

:py:class:`FactoryAggregate` is not overridable. Calling of
:py:meth:`FactoryAggregate.override` will result in raising of an
expection.

Next prototype might be the best demonstration of
:py:class:`FactoryAggregate` features:

.. literalinclude:: ../../examples/providers/factory_aggregate/prototype.py
:language: python
:linenos:

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
:linenos:

Listing of ``example.py``:

.. literalinclude:: ../../examples/providers/factory_aggregate/example.py
:language: python
:linenos:

.. disqus::
29 changes: 29 additions & 0 deletions examples/providers/factory_aggregate/example.py
@@ -0,0 +1,29 @@
"""`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
27 changes: 27 additions & 0 deletions examples/providers/factory_aggregate/games.py
@@ -0,0 +1,27 @@
"""Example games module."""


class Game(object):
"""Base game class."""

def __init__(self, player1, player2):
"""Initializer."""
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."""
17 changes: 17 additions & 0 deletions examples/providers/factory_aggregate/prototype.py
@@ -0,0 +1,17 @@
"""FactoryAggregate provider prototype."""


class FactoryAggregate(object):
"""FactoryAggregate provider prototype."""

def __init__(self, **factories):
"""Initializer."""
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]
2 changes: 1 addition & 1 deletion requirements-dev.txt
@@ -1,4 +1,4 @@
cython==0.27
cython==0.27.1
tox
unittest2
coverage
Expand Down

0 comments on commit 9305b9d

Please sign in to comment.