Messaging Made Easy With Azure Service Bus
Tags: dotnet, aspnetcore, azure, distributedsystems
Published: 2023-09-17 10:54:01

---
title: Messaging Made Easy With Azure Service Bus
published: true
date: 2023-02-11 00:00:00 UTC
tags: dotnet,aspnetcore,azure,distributedsystems
canonical_url: https://www.milanjovanovic.tech/blog/messaging-made-easy-with-azure-service-bus
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oi74myjwozst2i7g5vvi.png
---

If you're working in a **distributed system**, you need to be able to communicate between multiple services. There are a few ways that you can implement this. Depending on your chosen approach, you can either introduce tight coupling between your services or stay **loosely coupled**.

**Loose coupling** is an important quality in distributed systems. It allows you to evolve your services independently. So how do you implement loosely coupled **communication between services**?

You need a **messaging system**.

And [Azure Service Bus](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview)is an excellent choice.

In this week's newsletter, I'll show you how to create an **Azure Service Bus** instance, and how to implement messaging over a **queue**.

## Creating An Azure Service Bus Instance

You can create a new **Azure Service Bus** instance from the **Azure** portal.

I won't go into detail on that, since I find the **Azure** UI pretty intuitive.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2tetb9uo205fo0yny47.png)

After creating your **Azure Service Bus** instance, you'll need to do two more things:

- Create a new **queue**
- Find the **connection string**

After that you can proceed with implementing the pub-sub pattern over a queue. And you'll use the connection string from the Azure portal for connecting to the Azure Service Bus instance.

## Publishing Messages To The Azure Service Bus Queue

The first thing we need to do is to create the publishing side of our system, and then we'll see how we can process messages. We're going to use the `Azure.Messaging.ServiceBus` library to connect to the queue running in Azure Service Bus.

You can install the NuGet package by running the following command:

```csharp
Install-Package Azure.Messaging.ServiceBus
```

And now, let's write the code for publishing a message to an Azure Service Bus queue.

To work with the Azure Service Bus instance, you will use the [`ServiceBusClient`](https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebusclient?view=azure-dotnet)class. It requires a connection string to be able to connect to the Azure Service Bus instance.

The `ServiceBusClient` is safe to cache and reuse in the application, so it can be registered as a service with the singleton lifetime.

With the `ServiceBusClient` you can create a [`ServiceBusSender`](https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebussender?view=azure-dotnet)instance, which is responsible for sending the actual messages. You also need to specify which queue it will be sending messages to. This can also be the name of a topic, if you are publishing to a topic instead.

```csharp
using Azure.Messaging.ServiceBus;

await using var client = new ServiceBusClient(ConnectionString);

await using ServiceBusSender sender = client.CreateSender(QueueName);

// This will be the payload for the message ✉️
var productCreated = new ProductCreatedEvent(
    eventId: Guid.NewGuid(),
    product.Id,
    product.Name);

string json = JsonSerializer.Serialize(productCreated);

var message = new ServiceBusMessage(json);

await sender.SendMessageAsync(message);
```

As you can see, publishing a message to the queue is relatively simple.

We're creating a new instance of `ProductCreatedEvent`, which represents our message payload. The payload itself is serialized into a `JSON` string, wrapped inside a `ServiceBusMessage`.

For publishing messages to Azure Service Bus, you simply call the `SendMessageAsync` method.

## Receiving Messages From The Azure Service Bus Queue

Publishing messages to a queue is only half of the job. You also need to be able to receive messages from the queue. However, you'll see that this is very similar to the publishing side.

On the receiving side, you'll also need to create a `ServiceBusClient`. And then use it to create an instance of [`ServiceBusProcessor`](https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebusprocessor?view=azure-dotnet), which is used for consuming messages. You need to tell the `ServiceBusProcessor` which queue it will subscribe to.

The `ServiceBusProcessor` exposes two events, which represent callbacks for when a message is received. These events are [`ProcessMessageAsync`](https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebusprocessor.processmessageasync?view=azure-dotnet)and [`ProcessErrorAsync`](https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebusprocessor.processerrorasync?view=azure-dotnet).

You need to provide a handler for these two events, to properly consume messages from the queue. In the example below, we're using the `HandleMessageAsync` and `HandleErrorAsync` local functions.

```csharp
using Azure.Messaging.ServiceBus;

await using var client = new ServiceBusClient(ConnectionString);

await using ServiceBusProcessor processor = client.CreateProcessor(QueueName);

processor.ProcessMessageAsync += HandleMessageAsync;

processor.ProcessErrorAsync += HandleErrorAsync;

await processor.StartProcessingAsync();

async Task HandleMessageAsync(ProcessMessageEventArgs args)
{
    string json = args.Message.Body.ToString();

    var productCreated = JsonSerializer.Deserialize<ProductCreatedEvent>(json);

    Console.WriteLine(productCreated);

    await args.CompleteMessageAsync(args.Message);
}

Task HandleErrorAsync(ProcessErrorEventArgs args)
{
    var exception = args.Exception;

    Console.WriteLine(exception.ToString());

    return Task.CompletedTask;
}
```

The `ServiceBusProcessor` begins listening to messages coming from the queue after calling the `StartProcessingAsync` method.

Notice that the success and error event handlers need to accept the[`ProcessMessageEventArgs`](https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.processmessageeventargs?view=azure-dotnet)and [`ProcessErrorEventArgs`](https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.processerroreventargs?view=azure-dotnet), respectively.

From the `ProcessMessageEventArgs` you can access the `Message.Body` which contains the mesage payload.

## Further Reading

**Azure Service Bus** is a very feature rich service cloud. I showed you how to work with **queues** , which are great if you only have one publisher and one subscriber. However, if you need the ability to have multiple subscribers to a single message, you can't achieve this with queues.

You will have to use [topics](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-queues-topics-subscriptions#topics-and-subscriptions), and I invite you to research this _topic_ further (pun intended).

**Azure Functions** have excellent support for integrating with **Azure Service Bus**. You can define a `QueueTrigger` that will run your **Azure Function** when you receive a message to an Azure Service Bus **queue**.

I also released a video showing how to [publish and consume messages using RabbitMQ](https://youtu.be/CTKWFMZVIWA), and I think you might enjoy it after reading this newsletter.

Have an excellent weekend, and stay awesome!

* * *

**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 950+ 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 820+ engineers here.**](https://www.patreon.com/milanjovanovic)