From 75c65f334e879dac2d37344acaf2b3d8294f9ef5 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Sun, 16 Aug 2020 00:53:37 -0400 Subject: [PATCH] Update container provider type specialization docs --- docs/containers/specialization.rst | 24 ++++---- .../containers/declarative_provider_type.py | 59 +++++++------------ examples/containers/dynamic_provider_type.py | 44 +++++--------- 3 files changed, 48 insertions(+), 79 deletions(-) diff --git a/docs/containers/specialization.rst b/docs/containers/specialization.rst index 1c2619f1..724d0bd1 100644 --- a/docs/containers/specialization.rst +++ b/docs/containers/specialization.rst @@ -1,25 +1,25 @@ -Specialization of containers ----------------------------- +Specialization of the container provider type +--------------------------------------------- .. currentmodule:: dependency_injector.containers -:py:class:`DeclarativeContainer` could be specialized for any kind of needs -via declaring its subclasses. - -One of such `builtin` features is a limitation for providers type. - -Next example shows usage of this feature with :py:class:`DeclarativeContainer` -in couple with feature of :py:class:`dependency_injector.providers.Factory` -for limitation of its provided type: +You can make a restriction of the :py:class:`DeclarativeContainer` provider type: .. literalinclude:: ../../examples/containers/declarative_provider_type.py :language: python + :lines: 3- + :emphasize-lines: 29-31 -Limitation for providers type could be used with :py:class:`DynamicContainer` -as well: +The emphasized lines will cause an error because ``other_provider`` is not a subtype of the +``ServiceProvider``. This helps to control the content of the container. + +The same works for the :py:class:`DynamicContainer`: .. literalinclude:: ../../examples/containers/dynamic_provider_type.py :language: python + :lines: 3- + :emphasize-lines: 23 +The emphasized line will also cause an error. .. disqus:: diff --git a/examples/containers/declarative_provider_type.py b/examples/containers/declarative_provider_type.py index 2a755726..a52a2c43 100644 --- a/examples/containers/declarative_provider_type.py +++ b/examples/containers/declarative_provider_type.py @@ -1,48 +1,33 @@ -"""Specializing declarative container and factory provider example.""" +"""Declarative container provider type restriction example.""" -import collections +import abc -import dependency_injector.containers as containers -import dependency_injector.providers as providers -import dependency_injector.errors as errors +from dependency_injector import containers, providers -class SequenceProvider(providers.Factory): - """Sequence factory. - - Can provide only sequence objects. - """ - - provided_type = collections.Sequence +class Service(metaclass=abc.ABCMeta): + ... -class SequencesContainer(containers.DeclarativeContainer): - """IoC container. - - Can contain only sequence providers. - """ - - provider_type = SequenceProvider +class UserService(Service): + ... -if __name__ == '__main__': - try: - class _SequenceContainer1(SequencesContainer): - object_provider = providers.Factory(object) - except errors.Error as exception: - print(exception) - # can contain only - # instances +class ServiceProvider(providers.Factory): - try: - class _SequenceContainer2(SequencesContainer): - object_provider = SequenceProvider(object) - except errors.Error as exception: - print(exception) - # can provide only - # instances + provided_type = Service - class _SequenceContaier3(SequencesContainer): - list_provider = SequenceProvider(list) - assert _SequenceContaier3.list_provider() == list() +class ServiceContainer(containers.DeclarativeContainer): + + provider_type = ServiceProvider + + +class MyServices(ServiceContainer): + + user_service = ServiceProvider(UserService) + + +class ImproperServices(ServiceContainer): + + other_provider = providers.Factory(object) diff --git a/examples/containers/dynamic_provider_type.py b/examples/containers/dynamic_provider_type.py index fd1c0ac9..adbb6043 100644 --- a/examples/containers/dynamic_provider_type.py +++ b/examples/containers/dynamic_provider_type.py @@ -1,41 +1,25 @@ -"""Specializing dynamic container and factory provider example.""" +"""Dynamic container provider type restriction example.""" -import collections +import abc -import dependency_injector.containers as containers -import dependency_injector.providers as providers -import dependency_injector.errors as errors +from dependency_injector import containers, providers -class SequenceProvider(providers.Factory): - """Sequence factory. - - Can provide only sequence objects. - """ - - provided_type = collections.Sequence +class Service(metaclass=abc.ABCMeta): + ... -sequences_container = containers.DynamicContainer() -sequences_container.provider_type = SequenceProvider +class UserService(Service): + ... -if __name__ == '__main__': - try: - sequences_container.object_provider = providers.Factory(object) - except errors.Error as exception: - print(exception) - # can contain only - # instances +class ServiceProvider(providers.Factory): - try: - sequences_container.object_provider = SequenceProvider(object) - except errors.Error as exception: - print(exception) - # can provide only - # instances + provided_type = Service - sequences_container.list_provider = SequenceProvider(list) - assert sequences_container.list_provider() == list() +services = containers.DynamicContainer() +services.provider_type = ServiceProvider + +services.user_service = ServiceProvider(UserService) +services.other_provider = providers.Factory(object)