2017-07-04 64 views
1

我在Symfony 2.8項目中使用RabbitMQBundle,我想在發佈RabbitMQ消息之前使用自定義生成器類,它在數據庫中保留實體(消息)。如何將EntityManager訪問到RabbitMQBundle自定義生產者類中?

我config.yml定義的自定義製作類:

old_sound_rabbit_mq: 
    ... 
    producers: 
    myproducer: 
     class: AppBundle\Services\GenericProducer 
     connection: default 
     exchange_options: {name: 'my_exchange', type: direct} 

而定製生產類:

<?php 

namespace AppBundle\Services; 

use AppBundle\Entity\Message; 
use OldSound\RabbitMqBundle\RabbitMq\Producer; 

/** 
* Customised Producer, that publishes AMQP Messages 
* but also: 
* - writes an entry in the Message table 
*/ 
class GenericProducer extends Producer 
{ 
    /** 
    * Entity Manager 
    */ 
    protected $em; 


    public function setEntityManager($entityManager) 
    { 
     $this->em = $entityManager; 

     return $this; 
    } 

    /** 
    * Publishes the message and merges additional properties with basic properties 
    * And also: 
    * - writes an entry in the Message table 
    * 
    * @param string $action 
    * @param array $parameters 
    * @param string $routingKey 
    * @param array $additionalProperties 
    * @param array|null $headers 
    */ 
    public function publish($action, $parameters = array() , $routingKey = '', $additionalProperties = array(), array $headers = null) 
    { 
     $message = new Message(); 
     $message->setAction($action) 
      ->setParameters($parameters); 
     $this->em->persist($message); 
     $this->em->flush(); 

     $msgBody = array(
      'action' => $action, 
      'parameters' => $parameters 
     ); 
     parent::publish($msgBody, $routingKey, $additionalProperties, $headers); 
    } 
} 

我怎麼能做出GenericProducer->setEntityManager的調用,如生產者沒有定義在services.yml,像其他服務?

是否有另一種方法來實現這一目標?

謝謝你的時間。

回答

0

按照@lordrhodos的建議,我裝飾了由RabbitMQBundle生成的生產者服務。下面是完整的代碼:

config.yml(什麼特別要做):

old_sound_rabbit_mq: 
    ... 
    producers: 
    myproducer: 
     connection: default 
     exchange_options: {name: 'my_exchange', type: direct} 

services.yml(這裏定義的裝修服務):

app.decorating_myproducer_producer: 
     class: AppBundle\Services\GenericProducer 
     decorates: old_sound_rabbit_mq.myproducer_producer 
     arguments: ['@ 
app.decorating_myproducer_producer.inner', '@doctrine.orm.entity_manager'] 
     public: false 

裝修工等級

<?php 

namespace AppBundle\Services; 

use AppBundle\Entity\Message; 
use OldSound\RabbitMqBundle\RabbitMq\Producer; 

/** 
* Customised Producer, that publishes AMQP Messages 
* but also: 
* - writes an entry in the Message table 
*/ 
class GenericProducer extends Producer 
{ 
    /** 
    * @var Producer 
    */ 
    protected $producer; 

    /** 
    * @var EntityManager 
    */ 
    protected $em; 

    /** 
    * GenericProducer constructor. 
    * @param Producer $producer 
    * @param EntityManager $entityManager 
    */ 
    public function __construct(Producer $producer, EntityManager $entityManager) 
    { 
     $this->producer = $producer; 
     $this->em = $entityManager; 
    } 


    /** 
    * Publishes the message and merges additional properties with basic properties 
    * And also: 
    * - writes an entry in the Message table 
    * 
    * @param string $action 
    * @param array $parameters 
    * @param string $routingKey 
    * @param array $additionalProperties 
    * @param array|null $headers 
    */ 
    public function publish($action, $parameters = array() , $routingKey = '', $additionalProperties = array(), array $headers = null) 
    { 
     $message = new Message(); 
     $message->setAction($action) 
      ->setParameters($parameters); 
     $this->em->persist($message); 
     $this->em->flush(); 

     $msgBody = array(
      'action' => $action, 
      'parameters' => $parameters 
     ); 
     $this->producer->publish(serialize($msgBody), $routingKey, $additionalProperties, $headers); 

    } 
} 

最後,從控制器調用原始生產者:

$this->get('old_sound_rabbit_mq.myproducer_producer')->publish('wait', ['time' => 30]); 
相關問題