Using the same EntityListener for multiple entities with differrent service argument

做~自己de王妃 提交于 2021-02-10 07:25:51

问题


As an EntityListener is registered as a service, is it possible to register the same class multiple times with different argument and associate each of them with a particular entity ?

Considering the following entities :

/**
 * Class EntityA
 * @ORM\Entity
 * @ORM\EntityListeners({"myBundle\EventListener\SharedListener"})
 */
class EntityA implements sharedBehaviourInterface
{
    // stuff here
}

/**
 * Class EntityB
 * @ORM\Entity
 * @ORM\EntityListeners({"myBundle\EventListener\SharedListener"})
 */
class EntityB implements sharedBehaviourInterface
{
    // stuff here
}

I would like to register the following listener for both previous entities as this :

class SharedListener
{
    private $usefulParameter;

    public function __construct($usefulParameter)
    {
        $this->usefulParameter = $usefulParameter;
    }

    /**
     * @PrePersist
     *
     */
    public function prePersist(sharedBehaviourInterface $dbFile, LifecycleEventArgs $event)
    {
        // code here
    }

    // more methods
}

Using :

mybundle.entitya.listener:
    class: myBundle\EventListener\SharedListener
    arguments:
        - '%entitya.parameter%' # The important change goes here ...
    tags:
        - { name: doctrine.orm.entity_listener }
mybundle.entityb.listener:
    class: myBundle\EventListener\SharedListener
    arguments:
        - '%entityb.parameter%' # ... and here
    tags:
        - { name: doctrine.orm.entity_listener }

It does not work, and I'm actually surprised that the EntityListener declaration in the Entity targets the Listener class and not the service. Is it possible to target a specific service instead ? Like :

@ORM\EntityListeners({"mybundle.entityb.listener"})

Or what I'm trying to do isn't even possible ?


回答1:


You can inject other services into services with the @configured_service_id notation.This works for constructor arguments and setter injection.

Generally spoken: Do not try to find an abstraction where it isn't needed. Most of the time a little code duplication is far easier in long term.

I would simply built two independent listeners for each purpose.

Do a simple check that jumps out of the handler if the Entity is NOT one of the two Entities that should be handled with the same listener:

<?php
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;

class MyEventListener
{
    public function preUpdate(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();
        $entityManager = $args->getObjectManager();

        if (!$entity instanceof EntityA && !$entity instanceof EntityB) {
            return;
        }

        /* Your listener code */
    }
}



回答2:


Are you sure, this wouldn't do the trick:

public function prePersist(sharedBehaviourInterface $dbFile, LifecycleEventArgs $event)
{
    $entity = $event->getObject();

    if ($entity instanceof ClassA) {
        // Do something
    } elseif ($entity instanceof ClassB) {
        // Something else
    } else {
        // Nah, none of the above...
        return;
    }
}


来源:https://stackoverflow.com/questions/41975571/using-the-same-entitylistener-for-multiple-entities-with-differrent-service-argu

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