我正在尝试将我的一个服务注入EntityListener
,以便在实体更新时调用某些特定于应用程序的行为。
我的Logger
服务,用于在我的数据库中的LogEntry
实体中存储事件:
class Logger
{
/**
* @var EntityManager $manager The doctrine2 manager
*/
protected $manager;
//...
}
听众:
class EntityListener
{
public function __construct(Logger $logger)
{
$this->logger = $logger;
// ...
}
}
我的service.yml
中的服务定义:
listener:
class: Namespace\EntityListener
arguments: [@logger]
tags:
- { name: doctrine.event_listener, event: preUpdate }
logger:
class: Namespace\Logger
arguments: [@doctrine.orm.entity_manager]
不幸的是,它会导致ServiceCircularReferenceException
:
检测到服务的循环引用" doctrine.orm.default_entity_manager",路径:" doctrine.orm.default_entity_manager - > doctrine.dbal.default_connection - >听众 - >记录器"
问题显然是我将doctrine
注入我的服务,同时它也会自动注入我的监听器。我该怎么办?我找到a very similar question但接受的答案是注入容器,这显然是不利的。
有关如何解决我的问题的任何建议将不胜感激。
小方注意:如果可能的话,我想避免使用lazy services的解决方案。
答案 0 :(得分:2)
首先,我从EventListener
切换到EventSubscriber
。来自docs:
Doctrine定义了两种可以侦听Doctrine事件的对象:侦听器和订阅者。两者都非常相似,但听众更直接。
事实证明,可以通过传递的ObjectManager
- 参数访问$args
,如下所示:
/** @var Doctrine\Common\Persistence\ObjectManager $manager */
$manager = $args->getObjectManager();
所以要么直接在回调中使用它:
public function postUpdate(LifecycleEventArgs $args)
{
$manager = $args->getObjectManager();
// ...
...或将其设置为对象字段:
/** @var ObjectManager $manager */
private $manager;
public function postUpdate(LifecycleEventArgs $args)
{
$this->manager = $args->getObjectManager();
// ...
答案 1 :(得分:0)
在遇到同样的问题后,我发现使用延迟加载解决了我的问题。
listener:
class: AppBundle\EventListener\OrderDoctrineListener
tags:
- { name: doctrine.event_listener, event: postPersist, lazy: true }