Getting Started with MassTransit: Simplifying Messaging in .NET Applications
MassTransit is a .Net framework for building distributed applications. It provides an abstraction over the messaging technologies like Azure Service Bus, Amazon SQS and RabbitMQ.
So instead of using each of these messaging libraries with their own libraries why do we do the same operation with MassTransit? That was the question that I asked myself when I was learning MassTransit and the answer is that:
MassTransit is easier to integrate into a project and that makes us to think less about the configuration and focusing on business logic rather than configuration. Let’s say we were using Azure Service Bus and now we decided to change it to RabbitMQ. When we do that with MassTransit we only will need to change a small configuration code part and not all the code for changing the messaging library. So we are just changing the part that we said MassTransit to use Azure Service Bus. All other codes are staying as it was before.
We have talked what is MassTransit and why to use it. Now Let’s code it
Integration MassTransit to the project with RabbitMQ
I have created an Asp.Net Core Web API Project and added needed packages from Nuget:
- MassTransit
- MassTransit.RabbitMQ
If you’d like to try the demo yourself, you can either install RabbitMQ directly on your computer or set it up using a Docker container
MassTransit can use interaface, record and classes as message types. Now I will create a class which called as Message and it will be the type that we are going to publish to the rabbitmq.
Message.cs
public class Message
{
public int Id { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.Now;
public string body { get; set; }
}
MessageConsumer.cs
Here we created a MessageConsumer class and that’s because after publishinging a message to RabbitMQ we will consume it and in this class we are İmplementing IConsumer class which comes from MassTransit and we are giving the message type which is our Message Class in this case. And that’s how MassTransit know what to consume.
IConsumer make us to implement Consume method and in Consume method we are writing it as the way that we need to consume our message that we are publishing. For the demo I just consume the message and write it to the console via ILogger interface.
public class MessageConsumer : IConsumer<Message>
{
private readonly ILogger<MessageConsumer> _logger;
public MessageConsumer(ILogger<MessageConsumer> logger)
{
_logger = logger;
}
public async Task Consume(ConsumeContext<Message> context)
{
var message = context.Message.body;
_logger.LogInformation("Consuming message: " + message);
}
}
program.cs
Its time to complete the configuration on Program.cs file. What we are doing here is telling to MassTransit that we are using RabbitMQ as Messaging library, declaring the consumer that will consume the message and declaring the endpoint.
cfg.ReceiveEndpoint method creates a queue with the name that we are giving as parameter which is “message_queue” in this case.
builder.Services.AddMassTransit(x =>
{
x.AddConsumer<MessageConsumer>();
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("localhost", "/", h =>
{
h.Username("myuser");
h.Password("mypass");
});
cfg.ReceiveEndpoint("message_queue", e =>
{
e.ConfigureConsumer<MessageConsumer>(context);
});
});
});
HomeController.cs
I have created a controller and added a post method. Now its time to publish a message and see if our code will work as we expected or not.
Here I am calling Publish method with IPublishEndpoint interface and its coming from MassTransit.
When we publish a message because of our Program.cs configuration it will be automatically consuming it.
[ApiController]
[Route("[controller]")]
public class HomeController : ControllerBase
{
private readonly IPublishEndpoint _publishEndpoint;
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger,
IPublishEndpoint publishEndpoint)
{
_logger = logger;
_publishEndpoint = publishEndpoint;
}
[HttpPost("PublishEndPoint")]
public async Task<ActionResult> PublishEndPoint(Model.Message message)
{
await _publishEndpoint.Publish(message);
return Ok();
}
}
Here I have used IPublishEndpoint because my consumer is already up and I will publish and consume at the same time. If my consumer were not up and I still wanted to add it to a queue then we could use ISendEndpointProvider. Which is a better choice for the scenarios that the consumer will be up later. You can check it on MassTransit documentation.
Running the project
Because of creating as ASP.Net Core API project swagger added defaultly and I will make the test with it.
As in the image I have sent a request.
And here we can see the consumer is consuming it:
And we can see the exchanges and queues on RabbitMQ too as in the images.
If the consumer is not up then its adding the message to message_queue_skipped queue.
If you like to switch RabbitMQ to another framework like Azure Service bus or other framework that support by MassTransit you just need to update program.cs file configuration part that’s all. I have already said that as an advantage of MassTransit but I wanted to point that again after completing the integration.
Thanks for reading that was all that I wanted to point and tell about MassTransit. If you read the article till the end don’t forget to claps. And you can follow me on medium to hear more from me.
Thank you for reading and Happy Coding👋👋