Asp.net Microservices with RabbitMQ

In earlier post, I shared some fundamentals about microservices concepts, and how to get started with! Now we learn how to publish (like post method) to RabbitMQ service from c# microservice.

c# microservices with rabbitmq message service

Install RabbitMQ Or Use Hosted Service

Before we start with implementation, let's get RabbitMQ ready, either you can install RabbitMQ in your local environment, or you can use some RabbitMQ service provider.

So, if you want to install RabbitMQ in your local machine, here is the complete RabbitMQ installation guide. You may also need to install erlang, both components will take good amount of space in your system.

on the other hand, you can consume any ready to use RabbitMQ service, there are many providers, some of them are also providing free trial.

RabbitMQ Client for C# Developer

To consume RabbitMQ API, you need to install RabbitMQ client in your Microservice project, you can download client from Nuget package manager.

Simply right click on your project solution, open Nuget package manager and search for RabbitMQ.Client in search box. Once installed, just use the reference like using RabbitMQ.Client;.

Now your environment is ready to consume RabbitMQ service from c# microservice! in this example we will see when any new order is created, how the order information gets published to RabbitMQ service using built-in publish method.

RabbitMQ Client Implementation

Now, we write some code to connect and consume RabbitMQ.

Step 1:

Add RabbitMQ service connection information in appsettings.json file, create a new section like example below, then set all server credentials correctly, we use this information in code for connecting the service

"RabbitMQ": {
    "UserName": "wtr123",
    "Password": "pass123",
    "HostName": "1.02.10.103",
    "VHost": "/",
    "Port": 5670,
    "APIUrl":"",    
    "APIKey" :"",    
    "APISecretKey":""
},

Now create class with same structure as defined in above section, this class will help reading above configuration information while connecting the API.

public class RabbitMQ
{
    public string Username { get; set; }
    public string Password { get; set; }
    public string HostName { get; set; }
    public int Port { get; set; } = 5670;
    public string VHostUrl { get; set; } = "/";
    public string APIUrl { get; set; }
    public string APIKey { get; set; }
    public string APISecretKey { get; set; }
}

Create one IPooledObjectPolicy class, you need to add Microsoft.Extensions.ObjectPool reference. This class will establish RabbitMQ connection based on configuration information, and create a new channel object.

There are two methods in following class one Create and Return, Return method will check if the current channel object is still open and can be used, otherwise dispose the object

using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using System;
namespace MicroServiceOrder
{
    public class RabbitPooledObjectPolicy : IPooledObjectPolicy<IModel>
    {
        private readonly RabbitMQ _options;

        private readonly IConnection _connection;

        public RabbitPooledObjectPolicy(IOptions<RabbitMQ> optionsAccs)
        {
            _options = optionsAccs.Value;
            _connection = GetConnection();
        }


        private IConnection GetConnection()
        {
            var factory = new ConnectionFactory()
            {
                HostName = _options.HostName,
                UserName = _options.Username,
                Password = _options.Password,
                Port = _options.Port,
                VirtualHost = _options.VirtualHostUrl                 
            };
            return factory.CreateConnection();
        }

        public IModel Create()
        {
            return _connection.CreateModel();
        }

        public bool Return(IModel obj)
        {
            if (obj.IsOpen)
             return true;            
            else
            { 
                obj?.Dispose();
                return false;
            }
        }
    }
}
Microservice Publish Method Design

Here we create once interface called IRabbitManager with a method Publish, the method will allow to publish data from API controller

using Microsoft.Extensions.ObjectPool;
using Newtonsoft.Json;
using RabbitMQ.Client;
using System;
using System.Text;
namespace MicroServiceOrder
{
public interface IRabbitManager
{
void Publish<T>(T message, string exchangeName, string exchangeType, string routeKey)
where T : class;
}
public class RabbitManager : IRabbitManager
{
private readonly DefaultObjectPool<IModel> _objectPool;
public RabbitManager(IPooledObjectPolicy<IModel> objectPolicy)
{
_objectPool = new DefaultObjectPool<IModel>(objectPolicy, Environment.ProcessorCount * 2);
}
public void Publish<T>(T message, string exchangeName, string exchangeType, string routeKey)
where T : class
{
if (message == null)
return;
var channel = _objectPool.Get();
try
{
channel.ExchangeDeclare(exchangeName, exchangeType, true, false, null);
var sendBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message));
var properties = channel.CreateBasicProperties();
properties.Persistent = true;
channel.BasicPublish(exchangeName, routeKey, properties, sendBytes);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                _objectPool.Return(channel);
            }
        }
    }
}

Now we create an Extension class, which will help registering all these services in easiest way!

public static class RabbitServiceCollectionExtensions
{
    public static IServiceCollection AddRabbit(this IServiceCollection services, IConfiguration configuration)
    {
        var rabbitConfig = configuration.GetSection("RabbitMQ");
        services.Configure<RabbitMQ>(rabbitConfig);

        services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();

        services.AddSingleton<IPooledObjectPolicy<IModel>, RabbitPooledObjectPolicy>();
        services.AddSingleton<IRabbitManager, RabbitManager>();

        return services;
    }
}

Asp.Net Core C# Examples | Join Asp.Net MVC Course