В процессе миграции проекта symfony3.4 на Symfony4 с помощью symfony-flex…
После адаптации структуры каталогов и выполнения нескольких корректировок я теперь сталкиваюсь с тем, что выглядит как ошибка круговая зависимость, которая обнаруживается на этапе начальной загрузки контейнера службы приложений. Нажатие на приложение (с консоли или с внешнего интерфейса) вызывает некоторое исключение, связанное с Xdebug, говорящим «Достигнут предел вызовов вложенных функций ('256')».
Глядя на обратную трассировку, выявляется своего рода шаблон, который повторяется и приводит к выводу, что виноват не Xdebug, а две службы, косвенно зависящие друг от друга.
Вовлеченные услуги:
Менеджер журнала - это общедоступная служба, которая помогает сохранять действия пользователя в базе данных:
log_manager:
class: Service\Log\LogManager
public: true
arguments:
- "@doctrine.orm.entity_manager"
- "@?security.token_storage"
LoggableSubscriber использует службу LogManager для создания новой записи при изменении состояния некоторых объектов приложения:
Doctrine\Behavior\ORM\Loggable\LoggableSubscriber:
public: false
arguments:
- "@log_manager"
- "@event_dispatcher"
tags:
- { name: doctrine.event_subscriber }
Обратная трассировка(пожалуйста, прочтите снизу вверх):
==== ↑↑ PATTERN REPEATS ON AND ON ↑↑ ====
==== ONCE AGAIN DOCTRINE LOOKS FOR SUBSCRIBERS ====
at boDevDebugProjectContainer->load('…/var/cache/bo/dev/ContainerTv5AUyL/getLoggableSubscriberService.php')
in getDoctrine_Dbal_ApiacmeConnectionService.php (line 34)
at require('…/var/cache/bo/dev/ContainerTv5AUyL/getDoctrine_Dbal_ApiacmeConnectionService.php')
in boDevDebugProjectContainer.php (line 446)
at boDevDebugProjectContainer->load('…/var/cache/bo/dev/ContainerTv5AUyL/getDoctrine_Dbal_ApiacmeConnectionService.php')
in getDoctrine_Orm_ApiacmeEntityManagerService.php (line 74)
at require('…/var/cache/bo/dev/ContainerTv5AUyL/getDoctrine_Orm_ApiacmeEntityManagerService.php')
in boDevDebugProjectContainer.php (line 446)
==== "LOGMANAGER" NATURALLY REQUIRES DOCTRINE ENTITY MANAGER SERVICE ====
at boDevDebugProjectContainer->load('…/var/cache/bo/dev/ContainerTv5AUyL/getDoctrine_Orm_ApiacmeEntityManagerService.php')
in getLogManagerService.php (line 10)
at require('…/var/cache/bo/dev/ContainerTv5AUyL/getLogManagerService.php')
in boDevDebugProjectContainer.php (line 446)
at boDevDebugProjectContainer->load('…/var/cache/bo/dev/ContainerTv5AUyL/getLogManagerService.php')
in getLoggableSubscriberService.php (line 11)
==== BUT OUR "LOGGABLESUBSCRIBER" IN TURN NEEDS THE "LOGMANAGER" SERVICE ====
at require('…/var/cache/bo/dev/ContainerTv5AUyL/getLoggableSubscriberService.php')
in boDevDebugProjectContainer.php (line 446)
==== DOCTRINE LOADS SUBSCRIBERS (ATTACHED VIA "TAG" PROPERTY) ====
at boDevDebugProjectContainer->load('…/var/cache/bo/dev/ContainerTv5AUyL/getLoggableSubscriberService.php')
in getDoctrine_Dbal_ApiacmeConnectionService.php (line 34)
==== ↑↑ PATTERN STARTS HERE ↑↑ ====
at require('…/var/cache/bo/dev/ContainerTv5AUyL/getDoctrine_Dbal_ApiacmeConnectionService.php')
in boDevDebugProjectContainer.php (line 446)
at boDevDebugProjectContainer->load('…/var/cache/bo/dev/ContainerTv5AUyL/getDoctrine_Dbal_ApiacmeConnectionService.php')
in getDoctrine_Orm_ApiacmeEntityManagerService.php (line 74)
at require('…/var/cache/bo/dev/ContainerTv5AUyL/getDoctrine_Orm_ApiacmeEntityManagerService.php')
in boDevDebugProjectContainer.php (line 446)
==== FIRST, OUR "LOGMANAGER" SERVICE DEPENDS ON DOCTRINE MAIN ENTITYMANAGER ====
at boDevDebugProjectContainer->load('…/var/cache/bo/dev/ContainerTv5AUyL/getDoctrine_Orm_ApiacmeEntityManagerService.php')
in getLogManagerService.php (line 10)
at require('…/var/cache/bo/dev/ContainerTv5AUyL/getLogManagerService.php')
in boDevDebugProjectContainer.php (line 446)
↑↑ ↑↑ ↑↑
…
Это просто заблуждение? Или есть способ уведомить контейнер службы об этой ситуации, установив какое-то свойство / флаг где-нибудь в конфигурации, чтобы он не сошел с ума? Я видел несколько вопросов, связанных с этой темой, но ответы относятся к контексту их вопроса.
Я собирался разорвать зависимость службы LogManager от диспетчера сущностей доктрины, в результате чего класс LogManager больше не мог сохранять свой базовый объект сущности в базе данных сам по себе и, как следствие, делегировал это задание вызывающему контексту, возвращая вместо этого экземпляр для сохранения. Я не уверен, что это идеальное решение.
Предлагаемый подход был бы очень признателен. Спасибо.





Замена аргумента внедрение зависимости на вызов метода устранила проблему. Мое определение службы log_manager теперь выглядит так:
log_manager:
class: Service\Log\LogManager
public: true
arguments:
- "@?security.token_storage"
calls:
- ['setEntityManager', ["@doctrine.orm.entity_manager"]]
Прокомментируйте / ответьте, если есть лучший способ решить проблему.