如何将 RabbitMqBundle 生产者注入服务?

How to inject RabbitMqBundle producer into service?

我在将 RabbitMqBundle 中的 RabbitMq 生产者注入我的服务时遇到问题。

服务:

namespace App\Service;

use Carbon\Carbon;
use Doctrine\ORM\EntityManagerInterface;
use OldSound\RabbitMqBundle\RabbitMq\ProducerInterface;

class RatingPositionRecalculateService
{

    protected $entityManager;

    protected $positionProducer;

    public function __construct(EntityManagerInterface $entityManager, ProducerInterface $producer)
    {
        $this->entityManager = $entityManager;
        $this->positionProducer = $producer;
    }

    public function recalculate(Carbon $day)
    {
        // do stuff
    }

}

old_sound_rabbit_mq.yml:

old_sound_rabbit_mq:
    connections:
        default:
            url: ''

    producers:
        rating_position:
            connection:       default
            exchange_options: { name: 'rating_position', type: direct }

    consumers:
        rating_position:
            connection:       default
            exchange_options: {name: 'rating_position', type: direct}
            queue_options:    {name: 'rating_position'}
            callback:         rating_position_service

我得到:

Cannot autowire service "App\Service\RatingPositionRecalculateService": argument "$producer" of method "__construct()" references interface "OldSound\RabbitMqBundle\RabbitMq\ProducerInterface" but no such service exists. You should maybe alias this interface to the existing "old_sound_rabbit_mq.rating_position_producer" service. Did you create a class that implements this interface?

我试过使用 services.yml:

进行布线
rating_position_recalculate_service:
        class: App\Service\RatingPositionRecalculateService
        autowire: false
        arguments:
            $entityManager: '@doctrine.orm.entity_manager'
            $producer: '@old_sound_rabbit_mq.rating_position_producer'

但我仍然遇到同样的异常。

如果您只有一个制作人,您可以在 services.yaml:

中定义这样的别名
OldSound\RabbitMqBundle\RabbitMq\ProducerInterface: '@old_sound_rabbit_mq.rating_position_producer'

但我建议你为你的制作人创建一个空的 class:

// src/Producer/RatingPositionProducer.php

<?php

namespace App\Producer;

class RatingPositionProducer extends \OldSound\RabbitMqBundle\RabbitMq\Producer
{
}

然后,在您的 old_sound_rabbit_mq.yml 文件中:

old_sound_rabbit_mq:
    ...
    producers:
        rating_position:
           class: App\Producer\RatingPositionProducer
           ...

在您的 services.yaml 文件中:

App\Producer\RatingPositionProducer: '@old_sound_rabbit_mq.rating_position_producer'

最后,在你的 RatingPositionRecalculateService class

// src/Service/RatingPositionRecalculateService.php

namespace App\Service;

use Carbon\Carbon;
use Doctrine\ORM\EntityManagerInterface;
use App\Producer\RatingPositionProducer;

class RatingPositionRecalculateService
{
    ...

    public function __construct(EntityManagerInterface $entityManager, RatingPositionProducer $producer)
    {
        ...
    }

我认为您的问题与捆绑包无关。您的服务定义看起来不错。他们写在 the documentation:

Here we configure the connection service and the message endpoints that our application will have. In this example your service container will contain the service old_sound_rabbit_mq.upload_picture_producer and old_sound_rabbit_mq.upload_picture_consumer. The later expects that there's a service called upload_picture_service.

这意味着您应该有一项服务 old_sound_rabbit_mq.rating_position_producer。您可以使用命令 bin/console debug:cont --show-private | grep old_sound_rabbit_mq.

来验证它

但问题可能出在其他地方。

这是我的猜测:

  • 您有一个配置文件,可以将您的所有 类 注册为服务
  • 您的RatingPositionRecalculateService
  • 还有另一个配置文件

如果为真,则错误是由于您的服务重复注册造成的。在注册所有服务时,Symfony DIC 会尝试注册您的 RatingPositionRecalculateService 但不能 link 给生产者(因为生产者未在同一文件中注册)。您可能会看看另一个有类似问题的问题: