A Beginner's Guide to MassTransit and RabbitMQ in ASP NET
MassTransit is a powerful .NET library for building distributed systems. Let's learn how to set up MassTransit using RabbitMQ transport from an ASP NET application. We will also learn the default queue topology MassTransit sets up on RabbitMQ transport.
Table of Contents
MassTransit is a powerful .NET library for building distributed systems.
It simplifies messaging and event-driven architecture, making creating scalable and resilient applications easy.
MassTransit supports various message transports, including RabbitMQ, Amazon SQS, Azure Service Bus, etc. It abstracts away the complexities of different transports, providing a unified API for sending and receiving messages across these platforms.
In this post, let’s learn how to use MassTransit from an ASP NET application.
We will learn how to set up MassTransit and start using it to publish and subscribe to messages. I'll also show you the default queue topology that MassTransit sets up when working with RabbitMQ transport.
I will use an AWS MQ-hosted instance of RabbitMQ as my transport.
This post is sponsored by AWS and is part of my RabbitMQ Series.
Installing and Setting Up MassTransit in ASP NET Core
To install MassTransit with RabbitMQ in an ASP.NET Core application, run the following commands to add the required NuGet packages:
This will install MassTransit and the RabbitMQ transport, which we will configure later in this blog post.
Publishing Messages Using MassTransit
I am using a default ASP NET Core Web API application for the demo.
Let's say we have an POST
endpoint in it to add new weather forecast data to our application.
We must email a specific address whenever we add a weather forecast entry.
You could directly add the email sending logic to the application code that is responsible to add the new weather forecast.
However, this increases code coupling.
This makes it a perfect case to use message-driven architecture.
Any time new weather forecast data is added, let's raise WeaherDataAddedEvent
, as shown below.
The above code uses an instance ofIBus
from the MassTransit library to publish the WeatherDataAddedEvent
any time new weather forecast data is added.
IBus
will be automatically injected into the controller once we set up MassTransit later in this post.
Consuming Messages Using MassTransit
To consume a message in MassTransit, Create a consumer class that implements IConsumer<T>
, where T
is the message type you're consuming.
The SendNewWeatherDataEmail
class consumes the WeatherDataAddedEvent
published from our POST
endpoint.
The consumer implements IConsumer<WeatherDataAddedEvent>
interface.
Wiring MassTransit with RabbitMQ Transport
Now that we have set up our application code to publish messages and added a consumer for the message let's wire up MassTransit to use RabbitMQ as our transport mechanism.
If you are new to RabbitMQ, I highly recommend checking out the articles below to learn some basic concepts.
You can host a RabbitMQ instance in multiple ways. For this blog post, I use an AWS MQ-hosted instance of RabbitMQ.
The following code in Program.cs
registers MassTransit and sets up the RabbitMQ transport.
The code first registers the SendNewWeatherDataEmail
consumer class to MassTransit. This tells MassTransit about this consumer consuming the specific event.
We also set up to use RabbitMQ as the transport.
First, we retrieve the RabbitMQ configuration setting from appsettings.json and use that in the UsinRabbitMQ
extension method to set up the RabbitMQ host details and credentials to connect.
MassTransit Default Queue Topology Convention
The ConfigureEndpoints
the method sets up the channels and binding on RabbitMQ based on the default MassTransit convention.
MassTransit's default RabbitMQ topology setup:
Message Publication and Consumer Setup
MassTransit creates a fanout exchange named after the message type and class namespace (e.g., "hello_mass_transit:WeatherDataAddedEvent").
This is the primary point where publishers send messages.
For each consumer, MassTransit creates a unique queue named after the consumer (e.g., "SendNewWeatherDataEmail") and a fanout exchange, typically called the same (e.g., "SendNewWeatherDataEmail")
Message Routing and Flow
MassTransit binds the message type exchange to each consumer's exchange and each exchange to its corresponding queue.
This is an example of Exchange to Exchange Bindings in RabbitMQ.
The published message goes to the message type exchange and is forwarded to all bound consumer exchanges.
Each consumer exchange then routes the message to its specific queue. Consumers read messages from their dedicated queues.
This setup allows multiple consumers to handle the same message type independently.
Publishers and consumers are decoupled, enhancing system flexibility.
This topology ensures efficient message distribution, independent consumer scaling, and a clear, predictable structure for complex messaging systems.
MassTransit handles the creation and configuration of all these RabbitMQ objects automatically based on convention.
The default topology set up by MassTransit can be modified through configuration.
We will explore this in a future post! 👋
Rahul Nath Newsletter
Join the newsletter to receive the latest updates in your inbox.