Adventures with Messaging: Choose Your Own Messaging Service

I have been doing a lot with Azure messaging services of late, including Event Grid, Event Hub, Service Bus and Storage Queues.

In an effort to reduce the number of searches I do for C# code on how to work with these various messaging services in .NET Core, I have created a sample solution for how to send messages using an Azure Function project and App Service project, the code can be found at https://github.com/mattruma/MJR032.

Let’s first setup the Azure environment!

Setup the Azure environment

Navigate to the Azure portal.

Create a Resource Group, e.g. XXX-rg.

Create a Storage Account, e.g. XXXstgacc.

Copy the Connection String for later use to configure the Azure Function and App Service projects.

Add four Storage Queues called, funcapp1-messagea, funcapp1-messageb, webapp1-messagea and webapp1-messageb. These will be used by both the Storage Queue and Event Grid messaging services.

Create an Event Grid Topic, e.g. XXX-evtgrdtpc.

Copy the Topic Endpoint.

Copy the Topic Key.

Add four Event Subscriptions called funcapp1-messagea, funcapp1-messageb, webapp1-messagea and webapp1-messageb.

Each Event Subscription will be filtered by Event Type and mapped to one of the Storage Queues created in an early step.

Create an Event Hub Namespace, e.g. XXX-evthub.

In the Even Hub Namespace blade, click Shared access policies and then click the RootManageSharedAccessKeyPolicy and then copy the Connection string–primary key.

Add four Event Hubs called, funcapp1-messagea, funcapp1-messageb, webapp1-messagea and webapp1-messageb.

Create a Service Bus Namespace, e.g. XXX-svcbus.

In the Service Hub Namespace blade, click Shared access policies and then click the RootManageSharedAccessKeyPolicy and then copy the Primary Connection String.

Add four Queues called, funcapp1-messagea, funcapp1-messageb, webapp1-messagea and webapp1-messageb.

Your Azure environment is now all set!

Now let’s configure the code!

Setup the Azure Function, FuncApp1.csproj

Open the FuncApp1.csproj project in either Visual Studio or VS Code.

Create a local.settings.json file.

Add the following code snippet to your local.settings.json file:

{
   "IsEncrypted": false,
   "Values": {
     "AzureWebJobsStorage": "UseDevelopmentStorage=true",
     "FUNCTIONS_WORKER_RUNTIME": "dotnet",
     "EventGridMessageAddOptions:TopicKey": "EVENT_GRID_TOPIC_KEY",
     "EventGridMessageAddOptions:TopicEndpoint": "EVENT_GRID_TOPIC_ENDPOINT",
     "EventHubMessageAddOptions:ConnectionString": "EVENT_HUB_CONNECTION_STRING",
     "ServiceBusMessageAddOptions:ConnectionString": "SERVICE_BUS_CONNECTION_STRING",
     "StorageQueueMessageAddOptions:ConnectionString": "STORAGE_QUEUE_CONNECTION_STRING"
   }
}

Copy the values for the connection settings captured in previous steps into the local.settings.json file.

Setup the App Service, WebApp1.csproj

Open the WebApp1.csproj project in either Visual Studio or VS Code.

Create a appsettings.Development.json.

Add the following code snippet to your appsettings.Development.json file:

{
   "Logging": {
     "LogLevel": {
       "Default": "Debug",
       "System": "Information",
       "Microsoft": "Information"
     }
   },
   "EventGridMessageAddOptions": {
     "TopicKey": "EVENT_GRID_TOPIC_KEY",
     "TopicEndpoint": "EVENT_GRID_TOPIC_ENDPOINT"
   },
   "EventHubMessageAddOptions": {
     "ConnectionString": "EVENT_HUB_CONNECTION_STRING"
   },
   "ServiceBusMessageAddOptions": {
     "ConnectionString": "SERVICE_BUS_CONNECTION_STRING"
   },
   "StorageQueueMessageAddOptions": {
     "ConnectionString": "STORAGE_QUEUE_CONNECTION_STRING"
   }
 }

Copy the values for the connection settings captured in previous steps into the appsettings.Development.json file.

That’s it! Both apps are now ready to run!

Let’s take a quick look at the code.

The code

What does the code do? Great question!

The purpose of this code sample is to send two types of messages, MessageA and MessageB, through the designated messaging services.

Currently this sample supports the following messaging services: Event Grid, Event Hub, Service Bus, Storage Queue and a Fake messenger, great for testing.

The solution itself is made up of three projects:

  • The first project, Common.csproj, is a shared library, contains all the interfaces and concrete messaging services.
  • The second project is an Azure Function project, FuncApp1.csproj.
  • The third project is an App Service, specifically a Web Api, WebApp1.csproj.

Both the Azure Function and App Service projects send messages via a REST endpoint.

Common.csproj

This project is really the heart of the sample project.

There are a couple of pieces of code I would like to call out here, the first is the interface IMessageAdd.

All messaging services must implement the IMessageAdd interface, this will allow for easily switching out the message services.

Each messaging service has it’s own configuration settings which are passed in upon instantiation, via the constructor.

Each instance of the message service is prefixed with the technology used, e.g. EventGridMessageAdd and StorageQueueMessageAdd.

One thing to note, were I to use this code in production, I would split off each messaging service implementation into it’s project, enforcing separation of concerns and single responsibility.

FuncApp1.csproj and WebApp1.csproj

These projects are pretty similar as far as the code goes, with a couple of slight differences.

The wiring up of dependency injection in the Startup.cs files are a little different, the Web Api uses the Configuration class while the Azure Function uses Environment.GetEnvironmentVariable().

The Azure Function endpoints are HttpTriggers, while the Web Api endpoints are ApiControllers.

Right now both projects are configured to use Event Grid, but you can easily change this by toggling comments in Startup.cs.

// Choose your add message service

services
    .AddSingleton<IMessageAdd, EventGridMessageAdd>();
//services
//    .AddSingleton<IMessageAdd, EventHubMessageAdd>();
//services
//    .AddSingleton<IMessageAdd, ServiceBusMessageAdd>();
//services
//    .AddSingleton<IMessageAdd, StorageQueueMessageAdd>();
//services
//    .AddSingleton<IMessageAdd, FakeMessageAdd>();

The above code is for the WebApp1.csproj, the FuncApp1.csproj is almost the same, except services is replaced with builder.Services.

Included in the repository are Postman scripts to test both the Azure Function and App Service.

Test away!

That’s all I have for now!

Just a reminder, my initial purpose in sharing this article was to save myself a web search every now and then, but if this helps you out, please let me know!

Related Articles

Leave a Reply

Your email address will not be published.