In this exercise, I focused on only one Azure resource: Azure Service Bus. My goal was simple: run Service Bus locally as an emulator,
connect a console client project to it through .NET Aspire, and validate that the client can send and receive a message end-to-end.
How it looks like
This is the Service Bus emulator view

How I wired Azure Service Bus in Aspire AppHost
In AzureEmulators/AppHost.cs, I added Azure Service Bus as an emulator and defined a queue, a topic, and a subscription.
Then I connected the Service Bus client project with WithReference(serviceBus) and WaitFor(serviceBus).
- Azure Service Bus emulator resource:
azureServiceBus1 - Queue:
azureServiceQueue1 - Topic:
azureServiceTopic1 - Subscription:
azureServiceSubscriptionTopic1 - Client project reference:
ServiceBusClient1
var serviceBus = builder.AddAzureServiceBus("azureServiceBus1")
.RunAsEmulator();
var queue = serviceBus.AddServiceBusQueue("azureServiceQueue1");
var topic = serviceBus.AddServiceBusTopic("azureServiceTopic1");
topic.AddServiceBusSubscription("azureServiceSubscriptionTopic1");
builder.AddProject<Projects.ServiceBusClient>("ServiceBusClient1")
.WithReference(serviceBus)
.WaitFor(serviceBus)
;
What my ServiceBusClient project does
In ServiceBusClient/Program.cs, I implemented a startup flow to validate Service Bus connectivity and demonstrate message processing.
- I scan environment variables and pick the Service Bus connection string.
- I fail fast if the connection string is missing.
- I create a
ServiceBusClientusing that connection string. - I create a
ServiceBusProcessorfor the queueazureServiceQueue1. - I register a message handler to print received messages.
- I create a sender and send a test message.
- I wait for the message to be processed, then dispose the sender and client.
Code from my console client project
using Azure.Messaging.ServiceBus;
using System.Collections;
using System.Diagnostics;
Console.WriteLine("Hello,AzureServiceBus!");
string connectionStringAzureServiceBus = "";
foreach (var item in Environment.GetEnvironmentVariables().Cast<DictionaryEntry>())
{
if (item.Key?.ToString()?.Contains("azureServiceBus1") == true)
{
Console.WriteLine($"{item.Key}: {item.Value}");
connectionStringAzureServiceBus = item.Value?.ToString() ?? string.Empty;
}
}
if (string.IsNullOrWhiteSpace(connectionStringAzureServiceBus))
{
Console.WriteLine("AzureServiceBus connection string is not set in environment variables.");
return;
}
Console.WriteLine($"Connection string for Azure SQL: {connectionStringAzureServiceBus}");
ServiceBusClient client=new ServiceBusClient(connectionStringAzureServiceBus);
Console.WriteLine("Setting up the Service Bus processor...");
ServiceBusProcessor processor = client.CreateProcessor("azureServiceQueue1", new ServiceBusProcessorOptions());
processor.ProcessMessageAsync += (ProcessMessageEventArgs arg) =>
{
Console.WriteLine("!!!Received message: " + arg.Message.Body.ToString());
return Task.CompletedTask;
};
processor.ProcessErrorAsync += (ProcessErrorEventArgs arg) =>
{
Console.WriteLine("Error processing message: " + arg.Exception.ToString());
return Task.CompletedTask;
};
//do not put await here
processor.StartProcessingAsync();
Console.WriteLine("Starting the Service Bus sender...");
ServiceBusSender sender = client.CreateSender("azureServiceQueue1");
ServiceBusMessage message = new ServiceBusMessage("Hello, Andrei Ignat from Azure Service Bus!");
await sender.SendMessageAsync(message);
await Task.Delay(60_000);
await sender.DisposeAsync();
await client.DisposeAsync();
Output logs from my client project
Waiting for resource 'azureServiceBus1' to enter the 'Running' state. Waiting for resource 'azureServiceBus1' to become healthy. Waiting for resource ready to execute for 'azureServiceBus1'. Finished waiting for resource 'azureServiceBus1'. Hello,AzureServiceBus! ConnectionStrings__azureServiceBus1: Endpoint=sb://localhost:55217;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true; Connection string for Azure SQL: Endpoint=sb://localhost:55217;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true; Setting up the Service Bus processor... Starting the Service Bus sender... !!!Received message: Hello, Andrei Ignat from Azure Service Bus!
What is achieved
- I can run Azure Service Bus on my local PC without provisioning a cloud Service Bus namespace.
- I get dependency wiring from Aspire between AppHost and ServiceBusClient.
- I created a queue, a topic, and a subscription locally in the emulator.
- I proved messaging by sending a test message and receiving it through the processor.
- I now have a repeatable local loop for testing message-based architectures before deploying to Azure.
- I can experiment with queues and subscriptions while staying on my laptop.