Injecting EntityManager-dependend service into Listener

六眼飞鱼酱① 提交于 2019-12-06 06:52:54

问题


I am trying to inject one of my services into an EntityListener in order to call some application specific behaviour when an entity gets updated.

My Logger service, used to store events in a LogEntry entity in my database:

class Logger
{
    /**
     * @var EntityManager $manager The doctrine2 manager
     */
   protected $manager;
   //...
}

The listener:

class EntityListener
{
    public function __construct(Logger $logger)
    {
        $this->logger = $logger;
         // ...
    }
}

And the service definitions in my service.yml:

listener:
    class: Namespace\EntityListener
    arguments: [@logger]
    tags:
        - { name: doctrine.event_listener, event: preUpdate }

logger:
    class: Namespace\Logger
    arguments: [@doctrine.orm.entity_manager]

Unfortunately it results in a ServiceCircularReferenceException:

Circular reference detected for service "doctrine.orm.default_entity_manager", path: "doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> listener -> logger".

The problem obviously is that I inject the doctrine into the my service while it is also automatically injected into my listener. How do I proceed? I found a very similar question but the accepted answer is to inject the container which is obviously not favourable.

Any suggestions on how to solve my issue would be appreciated.


Small side note: I would like to avoid a solution depending on lazy services if possible.


回答1:


First of all I switched from an EventListener to an EventSubscriber. From the 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.

It turns out one can access the ObjectManager via the passed $args-parameter like so:

/** @var Doctrine\Common\Persistence\ObjectManager $manager */
$manager = $args->getObjectManager();

So either use it directly in the callback:

public function postUpdate(LifecycleEventArgs $args)
{
    $manager = $args->getObjectManager();
    // ...

...or set it to an object field:

/** @var ObjectManager $manager */
private $manager;

public function postUpdate(LifecycleEventArgs $args)
{
    $this->manager = $args->getObjectManager();
    // ...



回答2:


After struggling with the same problem, I found out that using lazy loading solved my issue.

listener:
    class: AppBundle\EventListener\OrderDoctrineListener
    tags:
        - { name: doctrine.event_listener, event: postPersist, lazy: true }


来源:https://stackoverflow.com/questions/34227467/injecting-entitymanager-dependend-service-into-listener

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!