我在Symfony 2.8项目中使用RabbitMQBundle,我想使用一个自定义生成器类,它在发布RabbitMQ消息之前将实体(Message)保留在数据库中。
我在config.yml中定义了自定义生成器类:
old_sound_rabbit_mq:
...
producers:
myproducer:
class: AppBundle\Services\GenericProducer
connection: default
exchange_options: {name: 'my_exchange', type: direct}
自定义Producer类:
<?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 :(得分:1)
生产者服务定义由Dependency Injection Extension of the bundle中的包动态生成。
您可以尝试decorate the existing service或创建compiler pass来获取现有服务,并通过调用wc -l tags
函数对其进行扩展。
答案 1 :(得分: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]);