如何将 EntityManager 访问到 RabbitMQBundle 自定义生产者 class?
How to access EntityManager into a RabbitMQBundle custom producer class?
我在 Symfony 2.8 项目中使用 RabbitMQBundle,我想使用自定义生成器 class,它在发布 RabbitMQ 消息之前在数据库中保留一个实体(消息)。
我在 config.yml 中定义了自定义生产者 class:
old_sound_rabbit_mq:
...
producers:
myproducer:
class: AppBundle\Services\GenericProducer
connection: default
exchange_options: {name: 'my_exchange', type: direct}
自定义制作人class:
<?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 中定义,就像其他服务一样?
还有其他方法可以实现吗?
感谢您的宝贵时间。
生产者服务定义由 Dependency Injection Extension of the bundle 中的包动态生成。
您可以尝试 decorate the existing service or create a compiler pass 获取现有服务并通过调用 setEntityManager
函数扩展它。
根据@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
装饰器class:
<?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]);
我在 Symfony 2.8 项目中使用 RabbitMQBundle,我想使用自定义生成器 class,它在发布 RabbitMQ 消息之前在数据库中保留一个实体(消息)。
我在 config.yml 中定义了自定义生产者 class:
old_sound_rabbit_mq:
...
producers:
myproducer:
class: AppBundle\Services\GenericProducer
connection: default
exchange_options: {name: 'my_exchange', type: direct}
自定义制作人class:
<?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 中定义,就像其他服务一样?
还有其他方法可以实现吗?
感谢您的宝贵时间。
生产者服务定义由 Dependency Injection Extension of the bundle 中的包动态生成。
您可以尝试 decorate the existing service or create a compiler pass 获取现有服务并通过调用 setEntityManager
函数扩展它。
根据@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
装饰器class:
<?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]);