Как в Symfony 4 передать контекст пользовательскому подписчику событий?

Я использую Symfony 4, и есть настраиваемое событие и подписчик, например. CustomEvent и CustomEventSubscriber. Есть модуль, который отправляет CustomEvent, например CustomModule. И этот модуль используется в контроллере (ControllerA) и команде (CommandB).

Другими словами, возможны два следующих сценария:

ControllerA -> CustomModule -> CustomEventSubscriber(CustomEvent)

Or

CommandB -> CustomModule -> CustomEventSubscriber(CustomEvent)

Логика в CustomEventSubscriber немного отличается в зависимости от того, где был вызван CustomModule (ControllerA или CommandB).

Как передать эту информацию CustomEventSubscriber?

Я могу добавить свойство $context в CustomEvent и установить его в CustomModule. Но в этом случае я должен передать информацию о контексте CustomModule.

Или, может быть, я могу использовать некоторые глобальные настройки, например контейнер?

Или создать двух разных подписчиков событий для каждого CustomEvent, отключить автоматическое подключение и «вручную» инициировать и добавить в диспетчер в ControllerA и CommandB?


person Andrey Lebedev    schedule 20.11.2019    source источник
comment
Что вы имеете в виду под контекстом? Можете ли вы добавить немного кода к своему вопросу, чтобы было понятнее, чего именно вы пытаетесь достичь?   -  person yivi    schedule 20.11.2019
comment
В любом случае вся необходимая информация должна быть включена в объект события.   -  person yivi    schedule 20.11.2019
comment
@yivi ›Под контекстом я подразумеваю то же, что и в контексте нормализации платформы API [api-platform.com/docs/core/serialization/, который передается с событием от одного подписчика к другому. Я начал использовать GenericEvent с дополнительными аргументами.   -  person Andrey Lebedev    schedule 20.11.2019
comment
Способ сделать это - передать любую информацию, которую вы хотите, в рамках вашего мероприятия. Создайте собственное событие с любыми свойствами, которые вам нужны, и именно этого должен ожидать ваш подписчик.   -  person yivi    schedule 20.11.2019
comment
Андрей, помог ли вам ответ ниже? Есть отзывы?   -  person yivi    schedule 23.11.2019


Ответы (1)


Нет необходимости создавать глобальные объекты, передавать контейнер или какой-либо другой механизм защиты от шаблонов.

Очевидное место для передачи информации, откуда отправляется событие, туда, где оно обрабатывается, - это само событие.

В идеале вы должны создать свой собственный настраиваемый класс событий с любыми свойствами, необходимыми для выполнения работы в дальнейшем.

Настраиваемое событие будет адаптировано к вашему приложению, и вы можете специально прослушивать эти события, не проверяя getSubject(), чтобы убедиться, что слушатель действительно должен его обрабатывать.

Использование Generic - это нормально, хотя и менее выразительно. Если вы dispatch(new CustomerCreatedEvent()), сразу станет ясно, что происходит.

Это событие, которое должен слушать ваш подписчик, и оно уже будет содержать всю необходимую информацию, собранную в контексте отправки.

person yivi    schedule 20.11.2019
comment
Окей. Какие плюсы и минусы использовать настраиваемое событие, которое расширяет Event vs GenericEvent? - person Andrey Lebedev; 20.11.2019
comment
Настраиваемое событие будет адаптировано к вашему приложению, и вы можете специально прослушивать эти события, не проверяя getSubject(), чтобы убедиться, что слушатель действительно должен его обрабатывать. Использование Generic - это нормально, хотя и менее выразительно. Если вы dispatch(new CustomerCreatedEvent()), сразу станет ясно, что происходит. - person yivi; 20.11.2019
comment
Я имел в виду, что создаю CustomerCreatedEvent, который расширяет GenericEvent, и мой подписчик ожидает этого типа события. Насколько я понимаю, разница между расширением Event и GenericEvent заключается в дополнительных параметрах события в виде свойств массива или объекта. - person Andrey Lebedev; 20.11.2019
comment
Возможно, вам следует знать, что GenericEvent был обесценен в 4.3 и исчезнет в 5.x. Может быть, взгляните на: Symfony \ Contracts \ EventDispatcher \ Event - person Cerad; 20.11.2019
comment
@Cerad У вас есть ссылка на эту отмену? Не могу найти ни его, ни @deprecated аннотации в исходном коде. Хотел бы добавить это к ответу. - person yivi; 20.11.2019
comment
@yivi Посмотрите в vendor / symfony / event-dispatcher / Event.php аннотацию амортизации. А поскольку GenericEvent расширяет Event, GenericEvent также обесценивается. Новое событие живет в vendor / symfony / event-dispatcher-contract. - person Cerad; 20.11.2019
comment
Спасибо @Cerad, очевидно, я смотрел не на тот класс. - person yivi; 20.11.2019
comment
@yivi - Похоже, я ошибался, говоря о прекращении GenericEvent. 5.0 только что был выпущен, а GenericEvent все еще существует. Он просто простирается от Contracts \ Event. Я до сих пор не вижу убедительных аргументов в пользу его использования, но похоже, что он будет существовать в неопределенном будущем. - person Cerad; 21.11.2019