#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 .