MassTransit and .NET Core DI - how to resolve dependencies with parameterless constructor?
If you are using the Microsoft.Extensions.DependencyInjection
container (which is the default with ASP.NET Core), then you will need the MassTransit.Extensions.DependencyInjection
package for MassTransit. Note that the package is currently only available as a pre-release version and also requires a pre-release version of MassTransit. Furthermore, the new package is part of a massive migration for .NET Standard, which still isn’t complete, so you should probably be a bit careful as there are likely going to be quite a few moving parts until the final release.
Since the package isn’t officially released, there also isn’t any documentation on it yet. But from looking at the pull request that introduced it and the current source, I think what you need to do is the following:
In Startup.ConfigureServices
, you need to add MassTransit, just like you would add other services:
services.AddMassTransit(c =>
{
c.AddConsumer<MyConsumer>();
c.AddConsumer<MyOtherConsumer>();
// or sagas
c.AddSaga<MySaga>();
});
// you still need to register the consumers/sagas
services.AddScoped<MyConsumer>();
services.AddScoped<MyOtherConsumer>();
services.AddSingleton<ISagaRepository<MySaga>, InMemorySagaRepository<MySaga>>();
In the configure action, you need to register you consumers and sagas in order for MassTransit to resolve them properly later.
Then, in your bus configuration, you would call LoadFrom
with the service provider:
sbc.ReceiveEndpoint(host, Configuration["QueueName"], e =>
{
e.LoadFrom(serviceProvider);
});
As for where you should do this (also in order to have access to the service provider), I would suggest you to do it in your Startup
’s Configure
method. The method can take any dependency as an argument, so you can easily inject the service provider there:
public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider, IApplicationLifetime applicationLifetime)
{
var bus = Bus.Factory.CreateUsingRabbitMq(sbc =>
{
var host = sbc.Host(new Uri("rabbitmq://localhost"), h =>
{
h.Username("guest");
h.Password("guest");
});
sbc.ReceiveEndpoint(host, Configuration["QueueName"], e =>
{
e.LoadFrom(serviceProvider);
});
});
// start/stop the bus with the web application
applicationLifetime.ApplicationStarted.Register(bus.Start);
applicationLifetime.ApplicationStopped.Register(bus.Stop);
}
One final disclaimer though: I personally haven’t used MassTransit, so I don’t really know if this makes actual sense for the library.
I also had the same issue and poke's answer didn't work for me as I needed to use DI for IBus
, IPublishEndpoint
and ISendEndpointProvider
. I actually found the solution in a deleted answer with a down vote on this very question. Shame really as it helped me.
I found this example here
services.AddSingleton(provider => Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = cfg.Host("localhost", "/", h => { });
cfg.ReceiveEndpoint(host, "web-service-endpoint", e =>
{
e.Consumer<DoSomethingConsumer>(provider);
});
}));