Шаблон наблюдателя Symfony — Как отправить пользовательское событие при установке свойства объекта?

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

На самом деле мне нужно изменить какое-то значение несвязанного объекта, каждый раз, когда изменяется определенное свойство объекта. Поэтому, чтобы разделить проблемы и отделить объекты, я хотел сделать это с помощью схемы наблюдателя. Я не хочу делать это в некоторых событиях доктрины, таких как preUpdate или аналогичных, так как они запускаются только при сбросе сущности, но мне нужно, чтобы это значение изменялось немедленно, чтобы гарантировать, что эти два значения всегда синхронизированы.

Поскольку вводить какой-либо сервис в сущность — это плохая практика, я не понимаю, как я могу это сделать?

Какие-либо предложения ?

1

Решение

С использованием диспетчер событий:

Событие, которое будет нести вашу информацию

class UpdateEntityEvent extends Event {
private $myEntity;
private $newValue;

public function __construct(Entity $entity, Whatever $newValue){
$this->myEntity = $entity;
$this->newValue = $newValue;
}
// [...] getters
}

Ваш слушатель

class UpdateMyEntityEventListener
{
public function updateCertainProperty(UpdateMyEntityEvent $event)
{
// Do what you want here :D
}
}

Некоторая конфигурация

 kernel.listener.updateMyEntity:
class: Acme\AppBundle\EventListener\UpdateMyEntityEventListener
tags:
- { name: kernel.event_listener, event: updateMyEntity, method: updateCertainProperty }

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

class MyEntityEvents
{
const UPDATE = 'updateMyEntity';
}

Тогда в вашем контроллере

public function updateAction()
{
// [...]
$event = new UpdateMyEntityEvent($entity, $whatever);
$dispatcher = $this->get('event_dispatcher')->dispatch( MyEntityEvents::UPDATE, $event);
1

Другие решения

Если вы хотите использовать шаблон наблюдателя, вам придется каким-то образом реализовать его самостоятельно. Как вы указали, Doctrine будет вычислять набор изменений вашей сущности только при запуске операции сброса, а не раньше. При этом, случается, что доктрина предлагает альтернативные политики отслеживания. NOTIFY Политика отслеживания поведения зависит именно от того, чего вы хотите достичь.

Я не предлагаю вам менять политику отслеживания вашей сущности, но вы можете воспользоваться существующими интерфейсами для реализации своего шаблона наблюдателя. Для этого, как объяснили в этом разделе документации, Ваша сущность, которую наблюдают, должна реализовать NotifyPropertyChanged интерфейс.

Оттуда вы можете реализовать PropertyChangedListener интерфейс непосредственно в другой сущности (или использовать конкретную службу, которая добавит себя в качестве прослушивателя вашей сущности в postLoad событие например?). Здесь это в основном зависит от отношений между вашими сущностями и от того, как вы можете присоединить слушателя к сущности, реализующей NotifyPropertyChanged,

Обратите внимание, что если вы сделаете это, UnitOfWork of Doctrine автоматически перехватит себя в качестве слушателя вашей сущности, но все равно будет полагаться на автоматическое вычисление изменений, если вы не добавите @ChangeTrackingPolicy("NOTIFY") аннотаций.

1

По вопросам рекламы [email protected]