Php Symfony观察者模式-设置实体属性时如何分派自定义事件?
是否有一种方法可以在每次调用某个实体setter时分派自定义事件 我实际上需要更改一个无关实体的某些值,每次更改某个实体属性时。因此,为了分离关注点和解耦对象,我想使用观察者模式来实现这一点。我不想在诸如“preUpdate”或类似事件中这样做,因为它们只在实体刷新时触发,但我需要立即更改此值以确保这两个值始终同步 由于向实体中注入任何服务都是不好的做法,我不知道如何才能做到这一点Php Symfony观察者模式-设置实体属性时如何分派自定义事件?,php,symfony,events,doctrine,observer-pattern,Php,Symfony,Events,Doctrine,Observer Pattern,是否有一种方法可以在每次调用某个实体setter时分派自定义事件 我实际上需要更改一个无关实体的某些值,每次更改某个实体属性时。因此,为了分离关注点和解耦对象,我想使用观察者模式来实现这一点。我不想在诸如“preUpdate”或类似事件中这样做,因为它们只在实体刷新时触发,但我需要立即更改此值以确保这两个值始终同步 由于向实体中注入任何服务都是不好的做法,我不知道如何才能做到这一点 有什么建议吗?使用事件调度程序: 传递您信息的事件 class UpdateEntityEvent extends
有什么建议吗?使用事件调度程序: 传递您信息的事件
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);
如果您希望使用observer模式,您必须以某种方式自己实现它。正如您所指出的,只有在触发刷新操作时,条令才会计算实体的变更集,而不是之前。话虽如此,但该学说恰好提出了这一点。
NOTIFY
跟踪策略行为完全取决于您希望实现的目标
我不是建议您更改实体的跟踪策略,而是建议您可以利用现有接口来实现您的观察者模式。如前所述,要做到这一点,被观察的实体需要实现接口
从那里,您可以直接在另一个实体中实现接口(或者使用一个特定的服务,该服务将在postLoad
事件中添加自己作为您的实体的侦听器)。在这里,它主要取决于实体之间的关系以及如何将侦听器附加到实现NotifyPropertyChanged
的实体
请注意,如果您这样做,条令的
UnitOfWork
将自动挂接自己作为实体的侦听器,但只要您不添加@ChangeTrackingPolicy(“NOTIFY”)
注释,它仍将依赖于自动变更集计算。是的,将服务注入实体是非常糟糕的做法。我不明白您为什么要记录不会刷新到DB的更改?我并没有说它不会刷新,我只是说我需要它同步,即使“尚未”刷新。您可以将您的实体包装到注入事件调度器的自定义服务中。该服务将在属性更改时发送自定义事件。是的,您是对的。但我在很多地方使用这个实体,没有任何服务,所以我希望我不必改变所有这些。。。我想我必须这么做。谢谢你。我理解你的提议。但这就是为什么这对我来说不是一个真正的解决方案:。。。我有许多控制器更新该属性,我必须将事件调度添加到所有控制器中。如果我忘记了一个,或者如果我从现在开始编写一个新的,我会记得这样做吗?我可以在使用persist/flush方法时说同样的话:我有许多控制器更新我的实体,如果我忘记了flush怎么办?我会记得那样做吗P您可以使用另一个服务,如EntityManager,并使用一个方法updateMyEntity()
,该方法可以将此逻辑保持在内部。但是如何以及何时添加侦听器呢?或者我可以在一个视频中捕捉事件吗?怎么做?就像我说的,这取决于你们两个实体之间的关系。到底是什么,有联系吗?没有联系。我有一个包含order和orderItem实体的电子商务包,现在我想在其中添加一个库存系统(解耦)。库存系统需要了解订单的任何数量变化。不知怎的,我觉得这样做是错误的。。。但是非常感谢你的帮助。