Обмен сообщениями Steeltoe с помощью RabbitMQ — проблема с прослушиванием и внедрением зависимостей

#c# #.net-core #rabbitmq #microservices #steeltoe

#c# #.net-ядро #rabbitmq #микросервисы #steeltoe

Вопрос:

Я использую Steeltoe для реализации обмена сообщениями о событиях с помощью RabbitMQ между микросервисами, но у меня возникает проблема, когда я регистрирую свою службу прослушивания, и она не распознает другие службы DI.

В моем Startup.cs файле мои службы регистрируются следующим образом:

 public void ConfigureServices(IServiceCollection servcies)
{
    ...

    // Add my custom service as a scoped service
    services.AddScoped<IMyService>(provider => new MyService());

    var rabbitSection = configuration.GetSection(RabbitOptions.PREFIX);
    services.Configure<RabbitOptions>(rabbitSection);

    services.AddRabbitServices();
    services.AddRabbitAdmin();
    services.AddRabbitTemplate();

    // Add Rabbit Listener Service
    services.AddSingleton<MyRabbitListenerService>();
    services.AddRabbitListeners<MyRabbitListenerService>();

    ...
}
 

… затем в моем MyRabbitListenerService.cs классе:

 public class MyRabbitListenerService
{
    private readonly IMyService _myService;

    public MyRabbitListenerService(IMyService myService)
    {
        _myService = myService;
    }

    [RabbitListener("MyQueue")]
    public async Task MessageListener(byte[] message)
    {
        // Do stuff ...
    }
}
 

Когда я запускаю это, я получаю сообщение об ошибке, указывающее IMyService , что не удалось внедрить в службу прослушивания, поскольку она не была зарегистрирована. Я не могу понять, почему это не работает. Это потому, что я пытаюсь внедрить службу с ограниченной областью действия в одноэлементную службу?

Обновить

Я провел некоторое тестирование, и изменение IMyService с службы с ограниченной областью действия на одноэлементный заставило его работать. Теперь мне нужно выяснить, как обойти это, потому что в моей ситуации не имеет смысла регистрировать IMyService как одноэлементный.

Ответ №1:

Причина этой ошибки заключается в том, что вы не можете использовать службу с ограниченной областью из синглтона. Scoped имеет семантику для каждого запроса, что для обмена сообщениями не имеет смысла. Возможно, вы имеете в виду AddTransient? Это работает. Если это не работает для вас, можете ли вы более подробно рассказать о том, почему MyService не может быть просто временным?

Комментарии:

1. Я мог бы сделать MyService временным, но в моем случае этот сервис представляет собой оболочку вокруг методов для взаимодействия с внешним веб-Api. Я бы предположил, что это было бы более подходящим для Scoped (или, может быть, даже Singleton).

2. Область действия — для HttpWebRequest, который предназначен для входящих запросов через конвейер ANC, где ваше приложение действует как сервер. RabbitListener — это длительный процесс, который прослушивает входящие сообщения, но это не HttpWebRequests. Если вам нужен новый объект для каждого сообщения RabbitMQ, правильный тип будет временным. В вашем случае, если вы используете HttpClient, правильным типом будет singleton .