I am working on the app using .NET Core 2 and MassTransit 4(dev).
Mass Transit requires parameterless constructor for consumers. I need to use e.g. logger, dbContext etc in my consumers and I would like to keep using native DI from .NET Core so I would prefer not to have to add Autofac etc (if possible?). It is causing the issue when .NET Core DI cannot inject my deps because my consumer is created with parameterless constructor...
Is there any way to resolve dependencies using native net core DI while having parameterless constructor OR is there some way of declaring endpoints of MassTransit which would allow to do that other than standard:
sbc.ReceiveEndpoint(host, Configuration["QueueName"],
e => { e.Consumer<MyAwesomeConsumer>();});
I have tried:
// =========== MASS TRANSIT ===============
var serviceProvider = services.BuildServiceProvider();
services.AddSingleton<MyAwesomeConsumer, MyAwesomeConsumer>();
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.Consumer(typeof(MyAwesomeConsumer), serviceProvider.GetService);
});
});
Application lifts up but as soon as first message arrives I am getting an error: MassTransit.ConsumerException: Unable to resolve consumer type 'AuthService.Integrations.MyAwesomeConsumer'.
I will appreciate any help. I hope it's clear what I am asking about.
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.