Где symfony DI собирает все зависимости?

Привет всем, хотел уточнить. Где symfony DI собирает все зависимости?
И через что (какой компонент) прокидывает зависимости в методы, свойства или конструктор?

Например контроллер
public function actionIndex(Request $r){
Переменная $r переданная через аргумент метода в контроллере
уже содержит в себе текущий инстанс Request
}

В каком месте приложения данный проброс (инжект) инстанса в метод actionIndex произошел?
  • Вопрос задан
  • 800 просмотров
Решения вопроса 2
prototype_denis
@prototype_denis
Symfony
Привет всем, хотел уточнить. Где symfony DI собирает все зависимости?


https://symfony.com/doc/current/components/depende...

И через что (какой компонент) прокидывает зависимости в методы, свойства или конструктор?


https://symfony.com/doc/current/service_container.html

В каком месте приложения данный проброс (инжект) инстанса в метод actionIndex произошел?


symfony.com/doc/current/components/dependency_inje...

Мне кажется вы неверно задаёте вопрос. "Где", "Через что", "В каком месте" - это прямая ссылка на исходники symfony https://github.com/symfony/symfony

Более разумно было бы отвечать на вопросы "Как" и "Почему".

Итак, DI. Что делает этот компонент.

Ему на вход прилетает конфигурация сервисов, неважно в каком формате и как. Yaml, php, xml и т.д. (хоть свой формат реализуйте)

Затем он разрешает зависимости и собирает контейнер. На выходе он отдаёт ContainerInterface.

Вот и всё, на этом и заканчивается основная логика этого компонента. Вся магия, до и после его основной работы.

Конфигурация - ребята добавили сахара и теперь конфигурация для компонента собирается с помощью рефлекции, которая за вас собирает аналог того же yaml файла со всеми прописанными агрументами, параметрами и прочими настройками для определённого сервиса.

(Что решает одну очень важную проблему - пролюбленные парметры, несуществующие зависимости обнаруживаются тут же, а не в рантайме)

Кэш - после основной работы DI - контейнер дампится в файл, лежит он обычно в var/cache/{env}/{container_name} и подключается в Kernel классе.

Именно там уже лежат все ваши агрументы для ваших классов, конктретные классы реализующие интерфейсы, абстракции и т.д.

В общем, для общего понимания.
  1. Собирается конфигурация сервисов (yaml, php, annotations, reflection, etc...)
  2. Собирается контейнер (В данный момент - агрументы сервисов, сами сервисы не имеют инстансов классов, всё в памяти и ввиде референсов)
  3. Дампиться контейнер (Тут происходит дамп инстансов, реальных классов)


Небольшое замечание.

Не кладите в методы классов вызовы к базе, к стороннему api и прочим 3-им серсвисам, если данный метод участвует в компиляции контейнера. Иначе вы не сможете поднять приложение.
Банальный пример. Если в какой-то команде в методе configure сделать запрос к базе, то без настроенного коннекта к базе или доступной базы вы не сможете нормально очистить кэш.

Вышеприведённыя ссылка - https://github.com/symfony/http-kernel/blob/master... для получение аргументов контроллера, отвечает даже не за "инклуд" в контролер сервисов, а за "инклуд" параметров запроса, сесиии и прочих.

В дополнение приведу вот эту ссылку https://github.com/symfony/http-kernel/blob/master... и вот эту https://github.com/symfony/http-kernel/blob/master...

Вот так компоненты http-kernel и di связаны друг с другом в данном случае.

Полноценный ответ тянет на цикл статей на хабре только по одному DI в symfony, здесь же постарался максимально кратко описать то "как оно работает", а не где и в каком месте. Надеюсь мой ответ будет хоть чем-то полезен.
Ответ написан
@Flying
Если говорить именно об аргументах контроллера, то они собираются в ArgumentResolver::getArguments() на основании метаданных (получаемых через reflection) из ArgumentMetadataFactory::createArgumentMetadata. Передача аргументов в action контроллера идёт при его вызове здесь.

Если же речь идёт об общем случае то там схема существенно сложнее т.к. непосредственно инициализация сервисов очень сильно отличается в зависимости от настроек контейнера в отношении конкретного сервиса (вспоминаем про factories, абстрактные сервисы и т.п.), но в общем случае все варианты приводят к генерации соответствующего метода в контейнере.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы