Use MassTransit + RabbitMQ with .Net Core 3.1
By: Feyyaz Acet
Tags: Mass Transit, Net Core, Messaging, Rabbitmq

Hi guys, this article has also a Turkish version. İf you want to read the Turkish version you can find here.

You know, In recent years microservices became high popular approach/architecture while you develop projects. And one of the important things is communication between them. So In this article, I will try the explain my experience with MassTransit and how I handled problems I had while I was developing async communication between microservices.

You know, In recent years microservices became high popular approach/architecture while you develop project. And one of the important thing is communication between them. So In this article, I will try the explain my experience with MassTransit and how I handled problems I had while I was developing async communication between microservices.

RabbitMq: It is a message broker that helps us make async communication between microservice or two services. In other words, it is a message-queued that enables messaging for common platforms.

Masstransit: It is a free, open-source, lightweight message bus used to create distributed applications using .Net technologies. We can also say that it is an abstraction structure between the message brokers we use for asynchronous messaging and our application. Although it is referred to as an ESB (enterprise service bus) in many places (including Wikipedia), they always state that they are not ESB in a humble manner. MassTransit supports Azure Service Bus, ActiveMQ and Amazon SQS / SNS message-queues along with

Rabbitmq. You do not need to write any extra code in the transformation between them.

So where does Masstransit come into play? Why do we need it?

I assume you have decided to apply microservice architecture and separate the dependencies of your application by bounded context or make some work asynchronous in your application. First, you must choose a message broker. (In our example, it will be Rabbitmq.) When you start using a message broker, you will face many challenges over time. Error management, retry, Circuit broker, transaction. At this point, our big brothers Chris Patterson and Dru Sellers met at alt.net in 2007 and had seen that they faced the same problems. These brothers started this project both themselves and us to not struggle so much.

What are the Masstransit Advantages ?

Opensource and free

Easy to use

It contains many microservice-message patterns (such as retry, circuit breaker, outbox).

Exception Handling comes as built-in.

Distributed transaction (Saga, event-driven state machines, routing-slip)

You can test easy

Monitoring

Things you need to know…

Messages

Messages in Masstransit use .Net System Types. It can be the Message Type class or interface. MassTransit recommends read-only properties and types without methods. Our brothers who developed this framework recommend the interface as the most suitable type based on their previous experiences. They even go a little further and state that many programmers define message contract as a base class as a common error and dispatch the base class on the consumer side, and then this process is painful.

There are 2 ways of transmitting the message in MassTransit. Publish and Send. If you will send an event, you must use Publish, and if it is command, you must use Send. When sending commands, we specify the endpoint (which queue to go to). However, we do not do this for Event. Publish follows the Publish-Subscribe pattern. In other words, when we publish the event, a message is sent to all queues that subscribe to our event.

There are 2 ways of transmitting the message in MassTransit. Publish and Send. If you will send an event, you must use Publish, and if it is a command, you must use Send. When sending commands, we specify the endpoint (which queue to go to). However, we do not do this for the Event. Publish follows the Publish-Subscribe pattern. In other words, when we publish the event, a message is sent to all queues that subscribe to our event.

Note: If you want to get information about the Publish-Subcribe pattern, let’s go here.

Events

Events should be published rather than forwarded(send to queue)directly to the enpoint. It means something happened. Events should be expressed in a noun-verb (past tense) sequence, indicating that something happened.

Events should be published rather than forwarded(send to queue)directly to the endpoint. It means something happened. Events should be expressed in a noun-verb (past tense) sequence, indicating that something happened.

Sample Events:

CustomerAddressUpdated

CustomerAccountUpgraded

OrderSubmitted,

OrderAccepted,

OrderRejected,

OrderShipped

Command

It is used when something needs to be done. It is recommended to use imperative mode.

Sample Commands

RegisterOrder,

UpdateCustomer

ChangeOrderState

In order not to go beyond the subject, I will not give an additional explanation about the terms. If you want to get more information about rabbitmq and terms, let’s go to my article about RabbitMq. You can find here

I would like to talk about our sample application without too much ado. I will also explain the structure used during development. I will give a short example from the process of the company that I have been a consultant. First of all, I will create a .net core web API project and receive customer demand from there. I will then queue this demand to save it. After that I will send a queue for this demand. On the consumer side, I will register this demand and publish event to send emails to the Customer Representative and integrate the third-party application. Finally, I will create 2 consumers (ThirPartyService and NotificationService) to handle an event.

I would like to talk about our sample application without too much ado. I will also explain the structure used during development. I will give a short example from the process of the company that I have been a consultant. First of all, I will create a .net core web API project and receive customer demand from there. I will then queue this request to save it. After that, I will send a queue for this demand. On the consumer side, I will register this demand and

publish events to send emails to the Customer Representative and integrate the third-party application. Finally, I will create 2 consumers (ThirPartyService and NotificationService) to handle an event.

Let’s start..?

I will develop the application on the windows platform with visual studio community edition with .net core 3.1. Additionally rabbitmq must be installed. I’ll get it up with docker. You can upload it yourself or follow the steps with me.

Let’s start by getting rabbitmq up with the docker. Running the following command will download the rabbitmq image in your local computer and launch it as a container.

docker run -d — hostname my-rabbit — name myrabbit -e RABBITMQ_DEFAULT_USER=guest -e RABBITMQ_DEFAULT_PASS=123456 -p 5672:5672 -p 15672:15672 rabbitmq:3-management

There is no problem, If the following screen opens when you try to enter http: //localhost: 5672 from the browser. I will not go into detailed information about Rabbitmq management panel. Let’s get it here if you’re wondering.

To work on a separate virtualhost in the project, I create a virtualhost named demand as follows. You can think of the virtual host as a separate domain/url that we will use for the application we will make.

Firstly, we create a blank solution called DemandMenagement. Subsequently, DemandMenagement.Api (Web Api) to receive the demand, DemandManagement.Registration (console) to save the demand to the database asynchronously, DemandManagement.Thirdparty.Service (console) to integrate the demand into a thirdparty project and DemandManagement.Notification (console )to report the demand to customer service. And finaly, create DemandManagement.MessageContracts (library) project to use common type (message contract). The final picture of the solution should be below.

I begin writing by define the interfaces that we will use in common. Inside the DemandManagement.MessageContracts project, I created the IRegisterDemandCommand interface to record the request and the IRegisteredDemandEvent interface to inform the consumers listening to the recorded demand. Along with these, I defined the BusConfigurator class as static to manage the bus, and RabbitMqConsts class for managing rabbitmq access and queue information. Now it’s time to install Masstrainsit.RabbitMQ package from Nuget. (We are installing this package for all our projects.) Likewise, all our projects will add the DemandManagement.MessageContracts project as a reference.

BusConfigurator Class

The final version of the BusConfigurator class is as it follows.

The final version of the RabbitMqConsts class is as it follows.

It’s time to write the api side. I created a folder named model in the root directory. And I created RegisterDemand class to post the demand. First of all, I add a controller called DemandControler. And I just configure the controller to post demand.

The final version of DemandController is as it follows

The final version of the RegisterDemandModel class is as it follows.

I use the BusConfigurator class to pass the request in the post action to the queue. However, I create an endpoint to forward the demand to the queue and send the message to the queue through this endpoint.

Post Action is as follows.

Then we move on to DemandManagement.Registration project. We add the DemandManagement.MessageContract project to our project as a reference and add the MassTransit.RabbitMQ package from Nuget.

In program.cs main method I am getting up the servicebus and subscribe to the registerdemand.service queue to listening. As soon as a record arrives in the relevant queue, it will be pushed here. Finaly create a class called RegisterDemandCommandConsumer to process the message.

Now, with the postman we will send our first demand to the queue and consume the demand on the DemandManagement.Registration side.

Before start, we right-click the properties on the solution, mark them as multiple startup projects from the Startup Project tab, and select the API and registration projects as a start. Then we get our projects up with F5.

Before start, we right-click the properties on the solution, mark them as multiple startup projects from the Startup Project tab, and select the API and registration projects as a start. Then we get our projects up with F5.

We open the Postman and post our demand with Postman as follows.

Postman: It is an application that we can easily call our Restful services.

The result of the post is as it follows.

Registiration consumer console. Information processed demand.

A queue named registerdemand.service has been created under the demand virtualhost on Rabbitmq side. MassTransit automatically created this for us. Likewise, it automatically created several exchanges to manage messages. Masstransit uses the Fanout exchange type by default. If anyone wants to get detailed information about exchanges, let me take him/her here.