I'm curious about the correct way to implement the EasyNetQ pub/sub pattern in an ASP.NET Core 2.x application. Specifically, I need to make sure that the lifecycle on all these resources are correct and that the subscription threads are owned/live properly.
I understand that IBus
should be a singleton.
Standard practice is to create a single IBus instance for the lifetime of your application. Dispose it when your application closes.
https://github.com/EasyNetQ/EasyNetQ/wiki/Connecting-to-RabbitMQ
So, that looks like this (although, I should use the various appsettings files to provide environment-specific connection strings... let's assume this is OK for the purposes of this question).
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IBus>(RabbitHutch.CreateBus("host=localhost"));
}
Now, I like the Auto Subscriber feature, but it's not obvious when/where to run the various subscribe methods.
You can use it to easily scan a specific assembly for classes that implement either of the interfaces IConsume or IConsumeAsync, and then let the auto subscriber subscribe these consumers to your bus.
It doesn't seem right to run that directly in the Startup context, right?
- Are the subscription threads "owned" by the correct parent thread (is there such a thing)?
- What's the expected/correct lifecycle for
AutoSubscriber
, isSingleton
even necessary? - Do I really even want to register
AutoSubscriber
? I don't want any other code to require it, I just need it easily/correctly accessible toConfigure
(seems like the right place to run a method likeSubscribeAsync
).
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IBus>(RabbitHutch.CreateBus("host=localhost"));
services.AddSingleton<AutoSubscriber>(provider => new AutoSubscriber(provider.GetRequiredService<IBus>(), Assembly.GetExecutingAssembly().GetName().Name));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.ApplicationServices.GetRequiredService<AutoSubscriber>().SubscribeAsync(Assembly.GetExecutingAssembly());
}
Should I use a Hosted Service, instead (should I implement the start/stop methods or is BackgroundService
OK)?