This article explains how to integrate MassTransit to an ASP.NET Boilerplate based project. It uses RabbitMQ with MassTransit as well and configures ASP.NET Boilerplates.
Introduction
MassTransit is a free, open-source distributed application framework for .NET. MassTransit makes it easy to create applications and services that leverage message-based, loosely-coupled asynchronous communication for higher availability, reliability, and scalability.
You can check MassTransit documentation and GitHub repository for more information.
Install RabbitMQ
We will use RabbitMQ with MassTransit. So, first thing we will do is install RabbitMQ. Go to installation documentation for Windows or select your operating system on the related page if you are not using Windows. Then, install the RabbitMQ to your computer.
Creating a Project
In order to integrate MassTransit, let's create a new project on https://aspnetboilerplate.com/Templates page. After creating the project, run the project by following the suggested Getting Started document which will be displayed to you after project creation. In order to use sample code in this article, you can use MassTransitSample
as the project name.
Create Publisher Project
In order to publish messages, we will create a separate web project. To do that, add an empty web project to your solution named MassTransitSample.Web.Publisher
.
After that, add packages below to created project:
<PackageReference Include="MassTransit.RabbitMQ" Version="8.0.6" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
Then, change the content of Program.cs file in the publisher project as shown below:
using MassTransit;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddMassTransit(mass =>
{
mass.UsingRabbitMq((context, cfg) =>
{
cfg.Host("localhost", "/", h =>
{
h.Username("guest");
h.Password("guest");
});
cfg.ConfigureEndpoints(context);
});
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.Run();
This will basically integrate Swagger and MassTransit to the publisher project.
In order to publish a message, add line below to your Program.cs right after app.UseHttpsRedirection();
app.MapPost("create-order", async (IBus bus, OrderDto order) =>
{
await bus.Publish(order);
});
Create OrderDto
In our message, we will use a DTO class to send our message. So, let's first create Orders folder, then Dto folder under Orders folder in MassTransitSample.Application
project and then create OrderDto
class as shown below under Orders/Dto folder.
public class OrderDto
{
public string OrderName { get; set; }
public decimal Price { get; set; }
}
Finally, add a reference to MassTransitSample.Application
in MassTransitSample.Web.Publisher
project, so we can use OrderDto
in publisher project.
We managed to publish messages from our Publisher project. So, now we need to configure our consumer project to receive and handle messages. In this sample, we will configure MassTransitSample.Web.Mvc
project but, you can apply same configuration to MassTransitSample.Web.Host
or any other web project you will add to your solution.
Add MassTransit NuGet package to your MVC project:
<ItemGroup>
<PackageReference Include="MassTransit.RabbitMQ" Version="8.0.10" />
</ItemGroup>
Then, create a consumer
to consume messages sent from Publisher project as shown below:
using System.Threading.Tasks;
using MassTransit;
using MassTransitSample.Orders.Dto;
using Microsoft.Extensions.Logging;
namespace MassTransitSample.Web.Orders
{
public class OrderConsumer : IConsumer<OrderDto>
{
private readonly ILogger<OrderDto> _logger;
public OrderConsumer(ILogger<OrderDto> logger)
{
_logger = logger;
}
public async Task Consume(ConsumeContext<OrderDto> context)
{
_logger.LogInformation("Received order {code} with price {price}",
context.Message.OrderName,
context.Message.Price
);
await Task.CompletedTask;
}
}
}
Since ASP.NET Boilerplate uses Castle.Windsor
for dependency injection, we will configure MassTransit
in a different way than the suggested approach in its default documentation.
In order to inject any service to our consumer
classes, we need to do this registration in PostInitialize
method so that it will be executed after ASP.NET Boilerplate completes registration of classes to dependency injection. To do this, go to MassTransitSampleWebMvcModule
and override PostInitialize
method and change its content as shown below:
public override void PostInitialize()
{
IocManager.IocContainer.Register
(Component.For<OrderConsumer>().LifestyleTransient());
var busControl = Bus.Factory.CreateUsingRabbitMq(config =>
{
config.Host(new Uri("rabbitmq://localhost/"), host =>
{
host.Username("guest");
host.Password("guest");
});
config.ReceiveEndpoint(queueName: "repro-service", endpoint =>
{
endpoint.Handler<OrderDto>(async context =>
{
using (var consumer = IocManager.ResolveAsDisposable
<OrderConsumer>(typeof(OrderConsumer)))
{
await consumer.Object.Consume(context);
}
});
});
});
IocManager.IocContainer.Register
(Component.For<IBus, IBusControl>().Instance(busControl));
busControl.Start();
}
After all, run the MassTransit.Publisher
app and MassTransit.Web.Mvc
app. Then, open /swagger URL on publisher app and send a message. This message will be handled by OrderConsumer
in MVC project.
Source Code
You can access the sample project on Github at https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/MassTransitSample.
History
- 18th January, 2023: Initial version