Dependency Injector — dependency injection фреймворк для Python
Привет,
Я создатель Dependency Injector. Это dependency injection фреймворк для Python.
В этом посте хочу рассказать про свой фреймворк.
Что такое dependency injection?
Принцип dependency injection позволяет снизить связывание (coupling) и увеличить сцепление (cohesion). Твой код становится более гибким, понятным и лучше поддается тестированию.
Как реализовать dependency injection?
Объекты больше не создают друг друга. Вместо этого они предоставляют способ передать им нужную зависимость.
Было:
class ApiClient:
def __init__(self):
self.api_key = os.getenv('API_KEY')
self.timeout = os.getenv('TIMEOUT')
class Service:
def __init__(self):
self.api_client = ApiClient()
Стало:
class ApiClient: def __init__(self, api_key: str, timeout: int): self.api_key = api_key self.timeout = timeout class Service: def __init__(self, api_client: ApiClient): self.api_client = api_clientКто теперь создает объекты? Смотри следующий пример.
Зачем нужен Dependency Injector?
Dependency Injector предоставляет тебе контейнер и набор провайдеров, которые помогают собирать объекты твоего приложении, когда ты применяешь принцип dependency injection:
from dependency_injector import containers, providers
class ApiClient:
def __init__(self, api_key: str, timeout: int):
self.api_key = api_key
self.timeout = timeout
class Service:
def __init__(self, api_client: ApiClient):
self.api_client = api_client
class Container(containers.DeclarativeContainer):
config = providers.Configuration()
api_client = providers.Singleton(
ApiClient,
api_key=config.api_key,
timeout=config.timeout.as_int(),
)
service = providers.Factory(
Service,
api_client=api_client,
)
if __name__ == '__main__':
container = Container()
container.config.from_yaml('config.yml')
service = container.service()
assert isinstance(service.api_client, ApiClient)
Тут можно посмотреть больше примеров.
Фреймворк простой. Реализован на Cython. Построен по принципу «явное лучше неявного (PEP20)». Не делает магических вещей с твоим кодом и не загрязняет его @inject декораторами, аннотациями, не очевидными правилами именования и типизации.
Что дальше?
- Загляни на Github проекта
- Пройди обучающее руководство:
- Flask и Dependency Injector: Документация, YouTube версия
- Aiohttp и Dependency Injector: Документация, YouTube версия
- Мониторинг демон на asyncio и Dependency Injector: Документация, YouTube версия
- CLI приложение на Dependency Injector: Документация, YouTube версия
- Попробуй использовать Dependency Injector на проекте
- Нужна будет помощь — пиши в комменты или личку
Если заинтересовался, но сомневаешься, просто попробуй применить подход пару раз. Он неинтуитивный. Нужно время чтобы привыкнуть и прочувствовать. Польза стает ощутимой, когда проект вырастает до 30+ компонентов в контейнере.
Сподобалась стаття? Підписуйтесь на автора, щоб отримувати сповіщення про нові публікації на пошту.

28 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів