Using MassTransit with RabbitMQ and Azure Service Bus
Tags: azure, microservices, aspnetcore, rabbitmq
Published: 2024-01-10 06:30:02

---
title: Using MassTransit with RabbitMQ and Azure Service Bus
published: true
date: 2024-01-06 00:00:00 UTC
tags: azure,microservices,aspnetcore,rabbitmq
canonical_url: https://www.milanjovanovic.tech/blog/using-masstransit-with-rabbitmq-and-azure-service-bus
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ui9af1r1nz9in5lbhmwg.png
---
[MassTransit](https://masstransit.io/) is an open-source distributed application framework for .NET. It provides a messaging abstraction on top of the supported message transports. MassTransit lets you focus on adding business value instead of worrying about messaging complexity.

MassTransit supports many message transport technologies. Here are a few that are popular:

- RabbitMQ
- Azure Service Bus
- Amazon SQS
- Kafka

In today's newsletter, I'll show you how to install and configure MassTransit in .NET. We'll connect MassTransit to a few message brokers - RabbitMQ and Azure Service Bus. And we will also cover how to publish and consume messages with MassTransit.

## Why Use MassTransit?

MassTransit solves many challenges of building distributed applications. You (almost) don't have to think about the underlying message transport. This allows you to focus on providing business value.

Here are a few things MassTransit does for you:

- **Message routing** - Type-based publish/subscribe, automatic broker topology configuration
- **Exception handling** - Messages can be retried or moved to an error queue
- **Dependency injection** - Service collection configuration and scope service provider
- **Request-Response** - Handle requests with automatic response routing
- **Observability** - Native [Open Telemetry (OTEL)](https://opentelemetry.io/) support
- **Scheduling** - Schedule message delivery using transport delay, Quartz.NET, or Hangfire
- **Sagas** - Reliable, durable, event-driven workflow orchestration

Let's see how to start using MassTransit.

## Installing and Configuring MassTransit with RabbitMQ

You need to install the `MassTransit` library. If you already have a message transport, you can install the respective transport library. Let's add the `MassTransit.RabbitMQ` library to configure [RabbitMQ](https://www.rabbitmq.com/) as the transport mechanism.

```csharp
Install-Package MassTransit

Install-Package MassTransit.RabbitMQ
```

Then, you can configure the required services for `MassTransit`. The `AddMassTransit` method accepts a delegate where you can configure many settings. For example, you can set the messaging endpoints to use kebab case naming by calling `SetKebabCaseEndpointNameFormatter`. This is also where you configure the transport mechanism. Calling `UsingRabbitMq` allows you to connect RabbitMQ as the transport mechanism.

```csharp
builder.Services.AddMassTransit(busConfigurator =>
{
    busConfigurator.SetKebabCaseEndpointNameFormatter();

    busConfigurator.UsingRabbitMq((context, configurator) =>
    {
        configurator.Host("localhost", "/", h =>
        {
            h.Username("guest");
            h.Password("guest");
        });

        configurator.ConfigureEndpoints(context);
    });
});
```

MassTransit takes care of setting up the required broker topology. RabbitMQ supports exchanges and queues, so messages are sent or published to exchanges. RabbitMQ routes those messages through exchanges to the appropriate queues.

You can start RabbitMQ locally inside a Docker container:

```csharp
docker run -d --name rabbitmq -p 5672:5672
```

## Configuring MassTransit with Azure Service Bus

[Azure Service Bus](https://azure.microsoft.com/en-us/products/service-bus)is a cloud-based message broker with support for queues and topics. MassTransit fully supports Azure Service Bus, including many advanced features and capabilities. However, you must be on the Standard or Premium tier of the Microsoft Azure Service Bus service.

To configure MassTransit to work with Azure Service Bus, you need to install the required transport library:

```csharp
Install-Package MassTransit.Azure.ServiceBus.Core
```

Then, you can connect to Azure Service Bus by calling `UsingAzureServiceBus` and providing the connection string. Everything else remains the same. MassTransit takes care of configuring the broker topology. MassTransit sends messages to topics, and Azure Service Bus routes those messages to the appropriate queues.

```csharp
builder.Services.AddMassTransit(busConfigurator =>
{
    busConfigurator.SetKebabCaseEndpointNameFormatter();

    busConfigurator.UsingAzureServiceBus((context, configurator) =>
    {
        configurator.Host("<CONNECTION_STRING>");

        configurator.ConfigureEndpoints(context);
    });
});
```

## Using the MassTransit In Memory Transport

You can also configure MassTransit to use an in-memory transport. It's useful for testing, because it doesn't require a message broker to be running. Another advantage is that it's fast.

However, there's a big problem with the in-memory transport - **it's not durable.**

If the message bus is stopped, all messages are lost. Don't use the in-memory transport for production systems.

It will only work on a single machine. So, it doesn't make sense for distributed applications.

```csharp
builder.Services.AddMassTransit(busConfigurator =>
{
    busConfigurator.SetKebabCaseEndpointNameFormatter();

    busConfigurator.UsingInMemory((context, configurator) =>
    {
        configurator.ConfigureEndpoints(context);
    });
});
```

## Message Types

MassTransit requires message types to be [reference types.](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types)So, you can use a `class`, `record` or `interface` to define a message.

You'll often create two types of messages: commands and events.

A command is an instruction to perform some action. Commands are intended to have exactly one consumer. Commands are expressed using verbs first: `CreateArticle`, `PublishArticle`, `ShareArticle`.

An event represents that something of significance happened. Events can have one or many consumers. Events should have a name in the past tense: `ArticleCreated`, `ArticlePublished`, `ArticleShared`.

Here's an example `ArticleCreated` message containing information about an article:

```csharp
public record ArticleCreated
{
    public Guid Id { get; init; }
    public string Title { get; init; }
    public string Content { get; init; }
    public DateTime CreatedOnUtc { get; init; }
}
```

Using `public set` or `public init` properties is recommended to avoid serialization problems with `System.Text.Json`.

## Publishing and Consuming Messages

You can use the `IPublishEndpoint` service to publish messages with MassTransit. The framework routes the message to the appropriate queue or topic based on the message type.

```csharp
app.MapPost("article", async (
    CreateArticleRequest request,
    IPublishEndpoint publishEndpoint) =>
{
    await publishEndpoint.Publish(new ArticleCreated
    {
        Id = Guid.NewGuid(),
        Title = request.Title,
        Content = request.Content,
        CreatedOnUtc = DateTime.UtcNow
    });

    return Results.Accepted();
});
```

To consume an `ArticleCreated` message, you need to implement the `IConsumer` interface. The `IConsumer` has one `Consume` method where you place your business logic. The consumer also gives you access to the `ConsumeContext`, which you can use to send further messages.

```csharp
public class ArticleCreatedConsumer(ApplicationDbContext dbContext)
    : IConsumer<ArticleCreatedEvent>
{
    public async Task Consume(ConsumeContext<ArticleCreatedEvent> context)
    {
        ArticleCreated message = context.Message;

        var article = new Article
        {
            Id = message.Id,
            Title = message.Title,
            Content = message.Content,
            CreatedOnUtc = message.CreatedOnUtc
        };

        dbContext.Add(article);

        await dbContext.SaveChangesAsync();
    }
}
```

MassTransit doesn't automatically know that the `ArticleCreatedConsumer` exists. You have to configure the consumer when calling `AddMassTransit`. The `AddConsumer` method registers the consumer type with the bus.

```csharp
builder.Services.AddMassTransit(busConfigurator =>
{
    busConfigurator.SetKebabCaseEndpointNameFormatter();

    busConfigurator.AddConsumer<ArticleCreatedConsumer>();

    // ...
});
```

## Next Steps

**MassTransit** is an excellent messaging library I often use when building distributed applications. The setup is straightforward, and there are only a few important abstractions. You need to know abstraction for publishing messages (`IPublishEndpoint`) and consuming messages (`IConsumer`). MassTransit takes care of doing the heavy lifting for you.

If you aren't already using it, I highly recommend adding MassTransit to your toolbox.

Here are some more practical **MassTransit learning resources** :

- [Request-Response pattern with MassTransit](https://youtu.be/NjsoykEOkrk)
- [RabbitMQ and MassTransit tutorial](https://youtu.be/CTKWFMZVIWA)
- [Microservices with RabbitMQ](https://youtu.be/MzC0PgYocmk)
- [Saga pattern with RabbitMQ](https://www.milanjovanovic.tech/blog/implementing-the-saga-pattern-with-rebus-and-rabbitmq)
- [Orchestration vs Choreography](https://www.milanjovanovic.tech/blog/orchestration-vs-choreography)
- [Messaging with Azure Service Bus](https://www.milanjovanovic.tech/blog/messaging-made-easy-with-azure-service-bus)

That's all for today.

See you next week.

* * *

P.S. Whenever you're ready, there are 2 ways I can help you:

1. [**Pragmatic Clean Architecture:**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting) This comprehensive course will teach you the system I use to ship production-ready applications using Clean Architecture. Learn how to apply the best practices of modern software architecture. [**Join 1,800+ students here.**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting)

2. [**Patreon Community:**](https://www.patreon.com/milanjovanovic) Think like a senior software engineer with **access to the source code** I use in my YouTube videos and **exclusive discounts** for my courses. [**Join 970+ engineers here.**](https://www.patreon.com/milanjovanovic)