Где symfony DI собирает все зависимости?
Привет всем, хотел уточнить. Где 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 классе.
Именно там уже лежат все ваши агрументы для ваших классов, конктретные классы реализующие интерфейсы, абстракции и т.д.
В общем, для общего понимания.Собирается конфигурация сервисов (yaml, php, annotations, reflection, etc...)Собирается контейнер (В данный момент - агрументы сервисов, сами сервисы не имеют инстансов классов, всё в памяти и ввиде референсов)Дампиться контейнер (Тут происходит дамп инстансов, реальных классов)
Небольшое замечание.
Не кладите в методы классов вызовы к базе, к стороннему 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, здесь же постарался максимально кратко описать то "как оно работает", а не где и в каком месте. Надеюсь мой ответ будет хоть чем-то полезен.
Если говорить именно об аргументах контроллера, то они собираются в ArgumentResolver::getArguments() на основании метаданных (получаемых через reflection) из ArgumentMetadataFactory::createArgumentMetadata. Передача аргументов в action контроллера идёт при его вызове здесь.
Если же речь идёт об общем случае то там схема существенно сложнее т.к. непосредственно инициализация сервисов очень сильно отличается в зависимости от настроек контейнера в отношении конкретного сервиса (вспоминаем про factories, абстрактные сервисы и т.п.), но в общем случае все варианты приводят к генерации соответствующего метода в контейнере.