diff --git a/docs/examples-other/index.rst b/docs/examples-other/index.rst index 457ff5b3..c0735f51 100644 --- a/docs/examples-other/index.rst +++ b/docs/examples-other/index.rst @@ -13,7 +13,7 @@ This sections contains assorted ``Dependency Injector`` examples. .. toctree:: :maxdepth: 2 - use_cases_miniapp + use-cases password-hashing chained_factories factory_of_factories diff --git a/docs/examples-other/password-hashing.rst b/docs/examples-other/password-hashing.rst index 6ad0173c..538a6bfa 100644 --- a/docs/examples-other/password-hashing.rst +++ b/docs/examples-other/password-hashing.rst @@ -3,6 +3,8 @@ Password hashing example This example demonstrates an injection of the ``Callable`` provider. +The source code is available on the `Github `_. + Listing of the ``example.py``: .. literalinclude:: ../../examples/miniapps/password-hashing/example.py @@ -14,6 +16,4 @@ Instructions for running: python example.py -You can find the source code on the `Github `_. - .. disqus:: diff --git a/docs/examples-other/use-cases.rst b/docs/examples-other/use-cases.rst new file mode 100644 index 00000000..0e59c3b9 --- /dev/null +++ b/docs/examples-other/use-cases.rst @@ -0,0 +1,71 @@ +Use cases example +================= + +.. currentmodule:: dependency_injector.providers + +This example demonstrates a usage of the ``DependenciesContainer`` provider. + +The source code is available on the `Github `_. + +Application structure +--------------------- + +Example application has next structure: + +.. code-block:: bash + + + ./ + └── example/ + ├── __init__.py + ├── __main__.py + ├── adapters.py + ├── containers.py + └── usecases.py + +Containers +---------- + +Listing of the ``example/containers.py``: + +.. literalinclude:: ../../examples/miniapps/use-cases/example/containers.py + :language: python + +Main module +----------- + +Listing of the ``example/__main__.py``: + +.. literalinclude:: ../../examples/miniapps/use-cases/example/__main__.py + :language: python + + +Run the application +------------------- + +Instructions for running in the "test" mode: + +.. code-block:: bash + + python run.py test example@example.com + +Instructions for running in the "prod" mode: + +.. code-block:: bash + + python run.py prod example@example.com + +Adapters and use cases +---------------------- + +Listing of the ``example/adapters.py``: + +.. literalinclude:: ../../examples/miniapps/use-cases/example/adapters.py + :language: python + +Listing of the ``example/usecases.py``: + +.. literalinclude:: ../../examples/miniapps/use-cases/example/usecases.py + :language: python + +.. disqus:: diff --git a/docs/examples-other/use_cases_miniapp.rst b/docs/examples-other/use_cases_miniapp.rst deleted file mode 100644 index 03aa7150..00000000 --- a/docs/examples-other/use_cases_miniapp.rst +++ /dev/null @@ -1,55 +0,0 @@ -Use cases mini application example ----------------------------------- - -.. currentmodule:: dependency_injector.providers - -"Use cases" miniapp demonstrate usage of :py:class:`DependenciesContainer` -provider. - -Example application -~~~~~~~~~~~~~~~~~~~ - -"Use cases" mini application has next structure: - -.. code-block:: bash - - use_cases/ - example/ <-- Example package - __init__.py - adapters.py - use_cases.py - containers.py <-- Dependency injection containers - run.py <-- Entrypoint - - -IoC containers -~~~~~~~~~~~~~~ - -Listing of ``use_cases/containers.py``: - -.. literalinclude:: ../../examples/miniapps/use_cases/containers.py - :language: python - -Run application -~~~~~~~~~~~~~~~ - -Listing of ``run.py``: - -.. literalinclude:: ../../examples/miniapps/use_cases/run.py - :language: python - -Instructions for running: - -.. code-block:: bash - - python run.py prod example@example.com # Running in "production" environment - python run.py test example@example.com # Running in "testing" environment - -Links -~~~~~ - -+ `Dependency Injector `_ -+ `Full example sources `_ - - -.. disqus:: diff --git a/examples/miniapps/use-cases/README.rst b/examples/miniapps/use-cases/README.rst new file mode 100644 index 00000000..c2de398a --- /dev/null +++ b/examples/miniapps/use-cases/README.rst @@ -0,0 +1,11 @@ +Use cases +========= + +This example demonstrates a usage of the ``DependenciesContainer`` provider. + +Instructions for running: + +.. code-block:: bash + + python -m example prod example@example.com + python -m example test example@example.com diff --git a/examples/miniapps/use-cases/example/__init__.py b/examples/miniapps/use-cases/example/__init__.py new file mode 100644 index 00000000..1c744ca5 --- /dev/null +++ b/examples/miniapps/use-cases/example/__init__.py @@ -0,0 +1 @@ +"""Top-level package.""" diff --git a/examples/miniapps/use_cases/run.py b/examples/miniapps/use-cases/example/__main__.py similarity index 56% rename from examples/miniapps/use_cases/run.py rename to examples/miniapps/use-cases/example/__main__.py index 873f908a..01d6741c 100644 --- a/examples/miniapps/use_cases/run.py +++ b/examples/miniapps/use-cases/example/__main__.py @@ -1,19 +1,23 @@ -"""Run 'Use Cases' example application.""" +"""Main module.""" import sys -from containers import Adapters, TestAdapters, UseCases +from .containers import UseCases, Adapters, TestAdapters -if __name__ == '__main__': - environment, email = sys.argv[1:] - +def main(environment: str, email: str) -> None: if environment == 'prod': adapters = Adapters() elif environment == 'test': adapters = TestAdapters() + else: + raise RuntimeError('Unknown environment') use_cases = UseCases(adapters=adapters) use_case = use_cases.signup() use_case.execute(email) + + +if __name__ == '__main__': + main(*sys.argv[1:]) diff --git a/examples/miniapps/use-cases/example/adapters.py b/examples/miniapps/use-cases/example/adapters.py new file mode 100644 index 00000000..c84496a4 --- /dev/null +++ b/examples/miniapps/use-cases/example/adapters.py @@ -0,0 +1,22 @@ +"""Adapters module.""" + +import abc + + +class EmailSender(metaclass=abc.ABCMeta): + + @abc.abstractmethod + def send(self, to: str, body: str) -> None: + ... + + +class SmtpEmailSender: + + def send(self, to: str, body: str) -> None: + print(f'Sending an email to {to} over SMTP, body="{body}"') + + +class EchoEmailSender: + + def send(self, to: str, body: str) -> None: + print(f'Fake sending an email to {to}, body="{body}"') diff --git a/examples/miniapps/use-cases/example/containers.py b/examples/miniapps/use-cases/example/containers.py new file mode 100644 index 00000000..f164c68f --- /dev/null +++ b/examples/miniapps/use-cases/example/containers.py @@ -0,0 +1,25 @@ +"""Containers module.""" + +from dependency_injector import containers, providers + +from . import adapters, usecases + + +class Adapters(containers.DeclarativeContainer): + + email_sender = providers.Singleton(adapters.SmtpEmailSender) + + +class TestAdapters(containers.DeclarativeContainer): + + email_sender = providers.Singleton(adapters.EchoEmailSender) + + +class UseCases(containers.DeclarativeContainer): + + adapters = providers.DependenciesContainer() + + signup = providers.Factory( + usecases.SignupUseCase, + email_sender=adapters.email_sender, + ) diff --git a/examples/miniapps/use-cases/example/usecases.py b/examples/miniapps/use-cases/example/usecases.py new file mode 100644 index 00000000..dd03f5c7 --- /dev/null +++ b/examples/miniapps/use-cases/example/usecases.py @@ -0,0 +1,22 @@ +"""Use cases module.""" + +import abc + +from .adapters import EmailSender + + +class UseCase(metaclass=abc.ABCMeta): + + @abc.abstractmethod + def execute(self) -> None: + ... + + +class SignupUseCase: + + def __init__(self, email_sender: EmailSender) -> None: + self.email_sender = email_sender + + def execute(self, email: str) -> None: + print(f'Sign up user {email}') + self.email_sender.send(email, f'Welcome, {email}') diff --git a/examples/miniapps/use_cases/README.rst b/examples/miniapps/use_cases/README.rst deleted file mode 100644 index 44db341b..00000000 --- a/examples/miniapps/use_cases/README.rst +++ /dev/null @@ -1,9 +0,0 @@ -Dependency Injector Use Cases example -===================================== - -Instructions for running - -.. code-block:: bash - - python run.py prod example@example.com # Running in "production" environment - python run.py test example@example.com # Running in "testing" environment diff --git a/examples/miniapps/use_cases/containers.py b/examples/miniapps/use_cases/containers.py deleted file mode 100644 index 847fada3..00000000 --- a/examples/miniapps/use_cases/containers.py +++ /dev/null @@ -1,30 +0,0 @@ -"""Dependency injection containers for 'Use Cases' example application.""" - -from dependency_injector import containers, providers - -from example.adapters import SmtpEmailSender, EchoEmailSender -from example.use_cases import SignupUseCase - - -class Adapters(containers.DeclarativeContainer): - """Adapters container.""" - - email_sender = providers.Singleton(SmtpEmailSender) - - -class TestAdapters(containers.DeclarativeContainer): - """Adapters container. - - This container is used for testing purposes. - """ - - email_sender = providers.Singleton(EchoEmailSender) - - -class UseCases(containers.DeclarativeContainer): - """Use cases container.""" - - adapters = providers.DependenciesContainer() - - signup = providers.Factory(SignupUseCase, - email_sender=adapters.email_sender) diff --git a/examples/miniapps/use_cases/example/__init__.py b/examples/miniapps/use_cases/example/__init__.py deleted file mode 100644 index bfa99aa2..00000000 --- a/examples/miniapps/use_cases/example/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Example top-level package.""" diff --git a/examples/miniapps/use_cases/example/adapters.py b/examples/miniapps/use_cases/example/adapters.py deleted file mode 100644 index d940cf0a..00000000 --- a/examples/miniapps/use_cases/example/adapters.py +++ /dev/null @@ -1,25 +0,0 @@ -"""Example adapters package.""" - - -class EmailSender: - """Abstract email sender.""" - - def send(self, to, body): - """Send email to specified email.""" - raise NotImplementedError() - - -class SmtpEmailSender: - """SMTP email sender uses SMTP protocol for sending emails.""" - - def send(self, to, body): - """Send email to specified email.""" - # Send email via SMTP - - -class EchoEmailSender: - """Echo email sender prints emails to stdout.""" - - def send(self, to, body): - """Send email to specified email.""" - print('Sending email to "{0}", body = "{1}"'.format(to, body)) diff --git a/examples/miniapps/use_cases/example/use_cases.py b/examples/miniapps/use_cases/example/use_cases.py deleted file mode 100644 index 4946ae46..00000000 --- a/examples/miniapps/use_cases/example/use_cases.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Example use cases package.""" - - -class UseCase: - """Abstract use case.""" - - def execute(self): - """Execute use case handling.""" - raise NotImplementedError() - - -class SignupUseCase: - """Sign up use cases registers users.""" - - def __init__(self, email_sender): - """Initialize instance.""" - self.email_sender = email_sender - - def execute(self, email): - """Execute use case handling.""" - print('Sign up user {0}'.format(email)) - self.email_sender.send(email, 'Welcome, "{}"'.format(email))