Use cases example — Dependency Injector 4.46.0 documentation (original) (raw)
This example demonstrates a usage of the DependenciesContainer
provider.
The source code is available on the Github.
Application structure¶
Example application has next structure:
./ └── example/ ├── init.py ├── main.py ├── adapters.py ├── containers.py └── usecases.py
Containers¶
Listing of the example/containers.py
:
"""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,
)
Main module¶
Listing of the example/__main__.py
:
"""Main module."""
import sys
from .containers import UseCases, Adapters, TestAdapters
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:])
Run the application¶
Instructions for running in the “test” mode:
python run.py test example@example.com
Instructions for running in the “prod” mode:
python run.py prod example@example.com
Adapters and use cases¶
Listing of the example/adapters.py
:
"""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}\"")
Listing of the example/usecases.py
:
"""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}")