Как внедрить EntityManager в потребителя RabbitMQBundle
Я следовал документации здесь , чтобы создать потребителя RabbitMQ, однако мне нужно иметь возможность использовать Доктрину EntityManager
в моем потребителе, и я не знаю, как это сделать.
Поскольку это команда, я попытался расширить ConainerAwareCommand
, однако сигнатура метода выполнения для потребителя несовместима с этим типом. Я не нашел очевидного способа переопределить конструктор и/или вызвать сеттер безрезультатно, даже если я создам его как службу.
Есть ли у кого-нибудь еще есть какой-нибудь опыт в том, как это сделать?
ИЗМЕНИТЬ:
Я уже пытался создать это как сервис, и у меня есть следующие сервисы.yml:
import.video:
class: Acme\DemoBundle\Service\Consumer\ImportVideoConsumer
arguments:
entityManager: @doctrine.orm.entity_manager
А потребитель выглядит так:
class ImportVideoConsumer implements ConsumerInterface
{
/**
* @var EntityManager
*/
private $entityMagager;
/**
* @param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
var_dump($entityManager);
}
/**
* Process the message
*
* @param AMQPMessage $msg
*/
public function execute(AMQPMessage $msg)
{
$body = json_decode($msg->body);
var_dump($this->entityMagager);
}
}
Когда я var_dump()
в конструкторе, я вижу, что экземпляр объекта создан правильно, однако, когда я var_dump()
в методе execute, свойство EntityManager равно НУЛЮ. Возможно ли, что экземпляр класса создается один раз для контейнера, но экземпляр, который переданный в команду экземпляр не создается через контейнер службы?
2 answers
Имя службы, которую вам нужно внедрить, - doctrine.orm.entity_manager
.
Поскольку я ооочень крут, вот пример emailConsumer
, где мы вводим как почтовую программу, так и EntityManager:
Если вы используете YML:
services:
acme_demo.consumer.email:
class: Acme\DemoBundle\Consumer\EmailConsumer
arguments:
mailer: "@mailer"
entityManager: "@doctrine.orm.entity_manager"
Если вы используете XML:
<service id="acme_demo.consumer.email" class="Acme\DemoBundle\Consumer\EmailConsumer">
<argument type="service" id="mailer" />
<argument type="service" id="doctrine.orm.entity_manager" />
</service>
В вашем потребителе:
class EmailConsumer implements ConsumerInterface
{
/**
* @var \Swift_Mailer
*/
private $mailer;
/**
* @var EntityManager $entityManager
*/
private $em;
public function __construct(\Swift_Mailer $mailer, $entityManager){
$this->mailer = $mailer;
$this->em = $entityManager;
}
public function execute(AMQPMessage $msg)
{
//Your logic here
}
}
Вы когда-нибудь сталкивались с исключением "Активной транзакции нет" при использовании доктрины у потребителя? У меня есть потребитель, который работает в фоновом режиме, и через пару часов я получил это сообщение об ошибке. Поэтому я должен перезапустить потребителя вручную.