Dependency Injector — dependency injection фреймворк для Python
Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті
Привет,
Я создатель 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 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів