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:
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{ "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
.
1 2 3 4 5 6 7 8 9 10 11 12 |
// 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
- https://docs.microsoft.com/en-us/dotnet/api/overview/azure/eventgrid?view=azure-dotnet
- https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-dotnet-standard-getstarted-send
- https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues
- https://docs.microsoft.com/en-us/azure/storage/queues/storage-dotnet-how-to-use-queues
- https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection
Discover more from Matt Ruma
Subscribe to get the latest posts sent to your email.