2017-02-01 3 views
1

Как EntityListener зарегистрирован как служба, можно ли зарегистрировать один и тот же класс несколько раз с разными аргументами и связать каждый из них с конкретным объектом?Использование одного и того же EntityListener для нескольких объектов с аргументом службы differrent

Учитывая следующие объекты:

/** 
* 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 
} 

Я хотел бы, чтобы зарегистрировать следующий перехватчик для обоих предыдущих организаций, так как это:

class SharedListener 
{ 
    private $usefulParameter; 

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

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

    // more methods 
} 

Использование:

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 } 

Это не работа, и я действительно удивлен, что объявление EntityListener в Entity нацелено на t он класс слушателя, а не сервис. Возможно ли настроить таргетинг на конкретную службу? Нравится:

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

Или что я пытаюсь сделать, даже не возможно?

ответ

1

Вы можете вводить другие услуги в службы с помощью нотации @configured_service_id.Это работает для аргументов конструктора и инжектора установки.

В целом говорят: не пытайтесь найти абстракцию там, где она не нужна. В большинстве случаев дублирование кода намного проще в долгосрочной перспективе.

Я бы просто построил двух независимых слушателей для каждой цели.

Выполните простую проверку, которая выскакивает из обработчика, если объект не один из двух лиц, которые должны быть обработаны с тем же слушателем:

<?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 */ 
    } 
} 
+0

Что вы подразумеваете под инъекцией других услуг в услуги? Я согласен с идеей «Не вкладывай слишком много абстракции». Если нет других вариантов, я сделаю это, но, возможно, мой главный вопрос должен быть следующим: как я могу делиться пост-устойчивым поведением между несколькими классами? –

+0

Каждый слушатель выполняется для каждого объекта. Вам не нужны два слушателя для одной и той же работы на разных объектах. – mblaettermann

0

Вы уверены, что это не будет делать трюк:

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; 
    } 
} 
Смежные вопросы