将依赖于 EntityManager 的服务注入 Listener
Injecting EntityManager-dependend service into Listener
我正在尝试将我的一项服务注入 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
:
Circular reference detected for service "doctrine.orm.default_entity_manager", path: "doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> listener -> logger".
问题显然是我将 doctrine
注入到我的服务中,同时它也自动注入到我的侦听器中。我该如何进行?我找到了 a very similar question 但公认的答案是 注入容器 这显然是不利的。
任何关于如何解决我的问题的建议都将不胜感激。
小提示:如果可能的话,我想避免依赖 lazy services 的解决方案。
首先,我从 EventListener
切换到 EventSubscriber
。来自 docs:
Doctrine defines two types of objects that can listen to Doctrine events: listeners and subscribers. Both are very similar, but listeners are a bit more straightforward.
事实证明,可以通过传递的 $args
参数访问 ObjectManager
,如下所示:
/** @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();
// ...
在遇到同样的问题后,我发现使用延迟加载解决了我的问题。
listener:
class: AppBundle\EventListener\OrderDoctrineListener
tags:
- { name: doctrine.event_listener, event: postPersist, lazy: true }
我正在尝试将我的一项服务注入 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
:
Circular reference detected for service "doctrine.orm.default_entity_manager", path: "doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> listener -> logger".
问题显然是我将 doctrine
注入到我的服务中,同时它也自动注入到我的侦听器中。我该如何进行?我找到了 a very similar question 但公认的答案是 注入容器 这显然是不利的。
任何关于如何解决我的问题的建议都将不胜感激。
小提示:如果可能的话,我想避免依赖 lazy services 的解决方案。
首先,我从 EventListener
切换到 EventSubscriber
。来自 docs:
Doctrine defines two types of objects that can listen to Doctrine events: listeners and subscribers. Both are very similar, but listeners are a bit more straightforward.
事实证明,可以通过传递的 $args
参数访问 ObjectManager
,如下所示:
/** @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();
// ...
在遇到同样的问题后,我发现使用延迟加载解决了我的问题。
listener:
class: AppBundle\EventListener\OrderDoctrineListener
tags:
- { name: doctrine.event_listener, event: postPersist, lazy: true }