Skip to content

Commit

Permalink
Merge 919e140 into 6af8181
Browse files Browse the repository at this point in the history
  • Loading branch information
rmk135 authored Aug 25, 2021
2 parents 6af8181 + 919e140 commit 4df75cb
Show file tree
Hide file tree
Showing 9 changed files with 4,158 additions and 3,918 deletions.
2 changes: 2 additions & 0 deletions docs/main/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ follows `Semantic versioning`_

Development version
-------------------
- Add support of non-string keys for ``FactoryAggregate`` provider.
- Improve ``FactoryAggregate`` typing stub.
- Improve resource subclasses typing and make shutdown definition optional
`PR #492 <https://github.com/ets-labs/python-dependency-injector/pull/492>`_.
Thanks to `@EdwardBlair <https://github.com/EdwardBlair>`_ for suggesting the improvement.
Expand Down
32 changes: 24 additions & 8 deletions docs/providers/factory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,11 @@ provider with two peculiarities:
Factory aggregate
-----------------

:py:class:`FactoryAggregate` provider aggregates multiple factories. When you call the
``FactoryAggregate`` it delegates the call to one of the factories.
:py:class:`FactoryAggregate` provider aggregates multiple 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``.
The aggregated factories are associated with the string keys. When you call the
``FactoryAggregate`` you have to provide one of the these keys as a first argument.
``FactoryAggregate`` looks for the factory with a matching key and calls it with the rest of the arguments.

.. image:: images/factory_aggregate.png
:width: 100%
Expand All @@ -165,8 +163,8 @@ rest of the arguments are passed to the delegated ``Factory``.
:lines: 3-
:emphasize-lines: 33-37,47

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
You can get a dictionary of the aggregated factories using the ``.factories`` attribute.
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
Expand All @@ -178,4 +176,22 @@ previous example you can do ``chess = game_factory.chess('John', 'Jane')``.
.. note::
When you inject the ``FactoryAggregate`` provider it is passed "as is".

To use non-string keys or keys with ``.`` and ``-`` you can provide a dictionary as a positional argument:

.. code-block:: python
providers.FactoryAggregate({
SomeClass: providers.Factory(...),
'key.with.periods': providers.Factory(...),
'key-with-dashes': providers.Factory(...),
})
Example:

.. literalinclude:: ../../examples/providers/factory_aggregate_non_string_keys.py
:language: python
:lines: 3-
:emphasize-lines: 30-33,39-40


.. disqus::
45 changes: 45 additions & 0 deletions examples/providers/factory_aggregate_non_string_keys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""`FactoryAggregate` provider with non-string keys example."""

from dependency_injector import containers, providers


class Command:
...


class CommandA(Command):
...


class CommandB(Command):
...


class Handler:
...


class HandlerA(Handler):
...


class HandlerB(Handler):
...


class Container(containers.DeclarativeContainer):

handler_factory = providers.FactoryAggregate({
CommandA: providers.Factory(HandlerA),
CommandB: providers.Factory(HandlerB),
})


if __name__ == "__main__":
container = Container()

handler_a = container.handler_factory(CommandA)
handler_b = container.handler_factory(CommandB)

assert isinstance(handler_a, HandlerA)
assert isinstance(handler_b, HandlerB)
Loading

0 comments on commit 4df75cb

Please sign in to comment.