.. _root_dependency_injection: Внедрение зависимостей ======================= Внедрение зависимостей (Dependency Injection, DI) — это паттерн проектирования, который помогает писать слабосвязанный, легко тестируемый и расширяемый код. Вместо того чтобы обработчики сами создавали нужные им объекты (зависимости), они лишь объявляют их в качестве аргументов. В момент вызова ``Argenta`` автоматически "внедряет" эти зависимости. ``Argenta`` использует библиотеку ``dishka`` для реализации DI, что позволяет декларативно объявлять зависимости прямо в сигнатурах ваших обработчиков. Подробнее о `DI`, `IoC` и API для создания провайдеров можно прочитать в `официальной документации dishka `_. Основная идея ------------- Представьте, что вашему обработчику для работы нужен доступ к базе данных. Вместо импорта и инициализации соединения внутри функции, вы просто объявляете его как аргумент с аннотацией типа: .. note:: ``argenta.di.FromDishka`` является псевдонимом для ``dishka.FromDishka``, и они полностью взаимозаменяемы. .. literalinclude:: ../code_snippets/dependency_injection/snippet.py :language: python :linenos: ``Argenta`` с помощью ``dishka`` разрешит зависимость по типу ``Connection`` и внедрит её. Но прежде чем использовать зависимость, её необходимо объявить в провайдере. .. literalinclude:: ../code_snippets/dependency_injection/snippet2.py :language: python :linenos: После создания провайдера его необходимо зарегистрировать в оркестраторе. .. literalinclude:: ../code_snippets/dependency_injection/snippet3.py :language: python :linenos: Как это работает? ----------------- В основе DI в Argenta лежат **провайдеры** и **контейнер**. * **Провайдер (Provider)** — это "рецепт", который объясняет, как создавать и настраивать ту или иную зависимость (например, подключение к БД, API-клиент или любой другой сервис). * **Контейнер (IoC Container)** — это "фабрика", которая хранит все рецепты (провайдеры) и по запросу создаёт и выдаёт готовые зависимости. Встроенные провайдеры ----------------------- ``Argenta`` поставляется со встроенным провайдером, который даёт доступ к важным системным зависимостям без дополнительной настройки. Например, вы можете получить объект ``ArgSpace``, который содержит аргументы командной строки, переданные при запуске приложения. Пример получения объекта ``ArgSpace`` и вывода в консоль значения аргумента `type`: .. literalinclude:: ../code_snippets/dependency_injection/snippet4.py :language: python :linenos: Обмен данными между хендлерами ------------------------------ Помимо DI, обработчики могут обмениваться данными в рамках сессии через **объект контекста**. В ``Argenta`` эту роль выполняет объект ``Response``. Каждый обработчик может записывать в него данные, а также читать, обновлять и удалять их. .. seealso:: Подробнее об этом можно прочитать в разделе :ref:`root_api_response`.