Excalibur.Dispatch.Transport.AzureServiceBus 3.0.0-alpha.19

This is a prerelease version of Excalibur.Dispatch.Transport.AzureServiceBus.
dotnet add package Excalibur.Dispatch.Transport.AzureServiceBus --version 3.0.0-alpha.19
                    
NuGet\Install-Package Excalibur.Dispatch.Transport.AzureServiceBus -Version 3.0.0-alpha.19
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Excalibur.Dispatch.Transport.AzureServiceBus" Version="3.0.0-alpha.19" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Excalibur.Dispatch.Transport.AzureServiceBus" Version="3.0.0-alpha.19" />
                    
Directory.Packages.props
<PackageReference Include="Excalibur.Dispatch.Transport.AzureServiceBus" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Excalibur.Dispatch.Transport.AzureServiceBus --version 3.0.0-alpha.19
                    
#r "nuget: Excalibur.Dispatch.Transport.AzureServiceBus, 3.0.0-alpha.19"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Excalibur.Dispatch.Transport.AzureServiceBus@3.0.0-alpha.19
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Excalibur.Dispatch.Transport.AzureServiceBus&version=3.0.0-alpha.19&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Excalibur.Dispatch.Transport.AzureServiceBus&version=3.0.0-alpha.19&prerelease
                    
Install as a Cake Tool

Excalibur.Dispatch.Transport.AzureServiceBus

Azure messaging transport implementation for the Excalibur framework, providing integration with Azure Service Bus, Event Hubs, and Storage Queues.

Overview

This package provides Azure messaging integration for Excalibur.Dispatch, enabling:

  • Azure Service Bus: Enterprise messaging with queues, topics, and sessions
  • Azure Event Hubs: High-throughput event streaming with partitions
  • Azure Storage Queues: Simple, cost-effective queue storage
  • CloudEvents Support: Standards-compliant structured and binary event formatting
  • Managed Identity: Passwordless authentication with Azure AD
  • Dead Letter Handling: Built-in dead letter queue support

Installation

dotnet add package Excalibur.Dispatch.Transport.AzureServiceBus

Configuration

Service Bus

Using Connection String
services.Configure<AzureServiceBusOptions>(options =>
{
    options.ConnectionString = "Endpoint=sb://mynamespace.servicebus.windows.net/;SharedAccessKeyName=...";
    options.QueueName = "my-queue";
});
services.Configure<AzureServiceBusOptions>(options =>
{
    options.Namespace = "mynamespace.servicebus.windows.net";
    options.QueueName = "my-queue";
});

services.Configure<AzureProviderOptions>(options =>
{
    options.UseManagedIdentity = true;
    options.FullyQualifiedNamespace = "mynamespace.servicebus.windows.net";
});
Environment Variables
AZURE_SERVICEBUS_CONNECTIONSTRING=Endpoint=sb://...
AZURE_SERVICEBUS_QUEUENAME=my-queue
services.Configure<AzureServiceBusOptions>(configuration.GetSection("Azure:ServiceBus"));

Event Hubs

Connection String
services.Configure<AzureEventHubOptions>(options =>
{
    options.ConnectionString = "Endpoint=sb://mynamespace.servicebus.windows.net/;...";
    options.EventHubName = "my-eventhub";
    options.ConsumerGroup = "$Default";
});
Managed Identity
services.Configure<AzureEventHubOptions>(options =>
{
    options.FullyQualifiedNamespace = "mynamespace.servicebus.windows.net";
    options.EventHubName = "my-eventhub";
    options.ConsumerGroup = "my-consumer-group";
});

Storage Queues

Connection String
services.Configure<AzureStorageQueueOptions>(options =>
{
    options.ConnectionString = "DefaultEndpointsProtocol=https;AccountName=...";
    options.QueueName = "my-queue";
});
Managed Identity
services.Configure<AzureStorageQueueOptions>(options =>
{
    options.StorageAccountUri = new Uri("https://mystorageaccount.queue.core.windows.net/");
    options.QueueName = "my-queue";
});

Authentication

services.Configure<AzureProviderOptions>(options =>
{
    options.UseManagedIdentity = true;
    options.FullyQualifiedNamespace = "mynamespace.servicebus.windows.net";
});

Required Azure RBAC roles:

  • Service Bus: Azure Service Bus Data Sender, Azure Service Bus Data Receiver
  • Event Hubs: Azure Event Hubs Data Sender, Azure Event Hubs Data Receiver
  • Storage Queues: Storage Queue Data Contributor
Service Principal
services.Configure<AzureProviderOptions>(options =>
{
    options.TenantId = "your-tenant-id";
    options.ClientId = "your-client-id";
    options.ClientSecret = "your-client-secret";
    options.FullyQualifiedNamespace = "mynamespace.servicebus.windows.net";
});
Key Vault Integration
services.Configure<AzureProviderOptions>(options =>
{
    options.KeyVaultUrl = new Uri("https://mykeyvault.vault.azure.net/");
    options.UseManagedIdentity = true;
});

Message Configuration

Service Bus Settings
services.Configure<AzureServiceBusOptions>(options =>
{
    // Connection
    options.Namespace = "mynamespace.servicebus.windows.net";
    options.QueueName = "my-queue";
    options.TransportType = ServiceBusTransportType.AmqpTcp;  // or AmqpWebSockets

    // Performance
    options.MaxConcurrentCalls = 10;     // Concurrent message processing
    options.PrefetchCount = 50;          // Messages to prefetch

    // CloudEvents
    options.CloudEventsMode = CloudEventsMode.Structured;  // or Binary

    // Error handling
    options.DeadLetterOnRejection = true;  // Send rejected messages to DLQ

    // Security
    options.EnableEncryption = false;
});
Event Hubs Settings
services.Configure<AzureEventHubOptions>(options =>
{
    // Connection
    options.FullyQualifiedNamespace = "mynamespace.servicebus.windows.net";
    options.EventHubName = "my-eventhub";
    options.ConsumerGroup = "$Default";

    // Performance
    options.PrefetchCount = 300;         // Events to prefetch
    options.MaxBatchSize = 100;          // Max events per batch

    // Processing
    options.StartingPosition = EventHubStartingPosition.Latest;  // or Earliest

    // Security
    options.EnableEncryption = false;
    options.EncryptionProviderName = null;

    // Debugging
    options.EnableVerboseLogging = false;
});
Storage Queue Settings
services.Configure<AzureStorageQueueOptions>(options =>
{
    // Connection
    options.StorageAccountUri = new Uri("https://mystorageaccount.queue.core.windows.net/");
    options.QueueName = "my-queue";

    // Processing
    options.MaxConcurrentMessages = 10;              // Concurrent processing
    options.MaxMessages = 10;                        // Messages per poll (max 32)
    options.PollingInterval = TimeSpan.FromSeconds(1);
    options.VisibilityTimeout = TimeSpan.FromMinutes(5);

    // Dead letter handling
    options.DeadLetterQueueName = "my-queue-dlq";
    options.MaxDequeueCount = 5;                     // Retries before DLQ

    // Security
    options.EnableEncryption = false;

    // Debugging
    options.EnableVerboseLogging = false;
    options.EmptyQueueDelayMs = 1000;
});

Retry Policies

services.Configure<AzureProviderOptions>(options =>
{
    options.RetryOptions = new AzureRetryOptions
    {
        MaxRetries = 3,                              // Retry attempts
        Delay = TimeSpan.FromSeconds(1),             // Initial delay
        MaxDelay = TimeSpan.FromSeconds(10),         // Max delay
        Mode = RetryMode.Exponential                 // or Fixed
    };
});

Health Checks

Registration

services.AddHealthChecks()
    .AddAzureServiceBusQueue(
        connectionString: "Endpoint=sb://...",
        queueName: "my-queue",
        name: "servicebus",
        tags: new[] { "ready", "messaging" });

Custom Health Check

public class ServiceBusHealthCheck : IHealthCheck
{
    private readonly AzureServiceBusHealthChecker _healthChecker;

    public async Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        try
        {
            var result = await _healthChecker.CheckHealthAsync(cancellationToken);
            return result.IsHealthy
                ? HealthCheckResult.Healthy()
                : HealthCheckResult.Degraded(result.Description);
        }
        catch (Exception ex)
        {
            return HealthCheckResult.Unhealthy("Service Bus unreachable", ex);
        }
    }
}

Production Considerations

Scaling

Service Bus
  • Use multiple processors with unique instance identifiers
  • Enable sessions for ordered processing per session ID
  • Use topics with subscriptions for pub/sub patterns
  • Scale out with competing consumers on queues
Event Hubs
  • Scale based on partition count (1 consumer per partition max)
  • Use consumer groups for multiple applications
  • Configure appropriate prefetch count for throughput
  • Consider Capture for archival to storage
Storage Queues
  • Simple horizontal scaling with multiple consumers
  • Lower throughput than Service Bus (~2000 messages/sec per queue)
  • Cost-effective for simple queue scenarios

Performance Tuning

Service Bus High-Throughput
services.Configure<AzureServiceBusOptions>(options =>
{
    options.MaxConcurrentCalls = 32;     // Increase concurrency
    options.PrefetchCount = 100;         // More prefetch
    options.TransportType = ServiceBusTransportType.AmqpTcp;  // Faster than WebSockets
});
Event Hubs High-Throughput
services.Configure<AzureEventHubOptions>(options =>
{
    options.PrefetchCount = 500;         // More prefetch
    options.MaxBatchSize = 100;          // Process in batches
});

Monitoring and Alerting

Key Azure Monitor metrics:

Service Metric Alert Threshold
Service Bus ActiveMessages > 10,000
Service Bus DeadLetteredMessages > 100
Service Bus ServerErrors > 0
Event Hubs IncomingMessages Baseline deviation
Event Hubs ThrottledRequests > 0
Storage Queues QueueMessageCount > 10,000

Security Best Practices

  1. Use Managed Identity instead of connection strings
  2. Enable Private Endpoints to restrict network access
  3. Configure RBAC with least-privilege roles
  4. Enable diagnostic logging for audit trails
  5. Use Key Vault for secrets when connection strings are required
  6. Enable encryption for sensitive data

Cost Optimization

  1. Choose the right tier: Basic, Standard, or Premium for Service Bus
  2. Use Standard tier Event Hubs for most scenarios (Premium for high throughput)
  3. Storage Queues are cheapest for simple queue patterns
  4. Auto-delete idle resources to avoid costs
  5. Set appropriate message TTL to avoid accumulation

Troubleshooting

Common Issues

Connection Refused
Azure.Messaging.ServiceBus.ServiceBusException: The connection was refused

Solutions:

  • Verify connection string format
  • Check namespace exists and is accessible
  • Verify firewall/network rules allow access
  • For managed identity, verify RBAC role assignments
Unauthorized Access
Azure.Identity.AuthenticationFailedException: ManagedIdentityCredential authentication unavailable

Solutions:

  • Enable managed identity on your Azure resource (App Service, VM, AKS)
  • Assign correct RBAC roles to the identity
  • For local development, use DefaultAzureCredential with Azure CLI login
Queue Not Found
Azure.Messaging.ServiceBus.ServiceBusException: Entity not found

Solutions:

  • Verify queue/topic name is correct (case-sensitive)
  • Check entity exists in the namespace
  • Verify connection string points to correct namespace
Message Lock Lost
Azure.Messaging.ServiceBus.ServiceBusException: The lock supplied is invalid

Solutions:

  • Increase message lock duration in queue settings
  • Process messages faster
  • Use auto-renew lock feature
  • Avoid long-running synchronous operations

Logging Configuration

{
  "Logging": {
    "LogLevel": {
      "Excalibur.Dispatch.Transport.AzureServiceBus": "Debug",
      "Azure.Messaging.ServiceBus": "Information",
      "Azure.Messaging.EventHubs": "Information",
      "Azure.Core": "Warning"
    }
  }
}

Debug Tips

  1. Enable Application Insights for distributed tracing
  2. Use Service Bus Explorer to inspect queues/topics
  3. Check Azure Monitor logs for service-side errors
  4. Test with Azure Portal to verify queue accessibility
  5. Enable diagnostic settings on Service Bus namespace

Complete Configuration Reference

Service Bus

services.Configure<AzureServiceBusOptions>(options =>
{
    // Connection
    options.Namespace = "mynamespace.servicebus.windows.net";
    options.QueueName = "my-queue";
    options.ConnectionString = null;  // Or use connection string
    options.TransportType = ServiceBusTransportType.AmqpTcp;

    // Performance
    options.MaxConcurrentCalls = 10;
    options.PrefetchCount = 50;

    // CloudEvents
    options.CloudEventsMode = CloudEventsMode.Structured;

    // Error handling
    options.DeadLetterOnRejection = false;

    // Security
    options.EnableEncryption = false;
});

services.Configure<AzureProviderOptions>(options =>
{
    // Authentication
    options.UseManagedIdentity = true;
    options.FullyQualifiedNamespace = "mynamespace.servicebus.windows.net";
    options.TenantId = "";
    options.ClientId = "";
    options.ClientSecret = "";

    // Azure metadata
    options.SubscriptionId = "";
    options.ResourceGroup = "";

    // Key Vault
    options.KeyVaultUrl = null;

    // Storage (for checkpointing)
    options.StorageAccountName = "";
    options.StorageAccountKey = "";
    options.StorageAccountUri = null;

    // Settings
    options.MaxMessageSizeBytes = 262144;  // 256 KB
    options.EnableSessions = false;
    options.PrefetchCount = 10;

    // Retry
    options.RetryOptions = new AzureRetryOptions
    {
        MaxRetries = 3,
        Delay = TimeSpan.FromSeconds(1),
        MaxDelay = TimeSpan.FromSeconds(10),
        Mode = RetryMode.Exponential
    };
});

Event Hubs

services.Configure<AzureEventHubOptions>(options =>
{
    // Connection
    options.ConnectionString = null;
    options.FullyQualifiedNamespace = "mynamespace.servicebus.windows.net";
    options.EventHubName = "my-eventhub";
    options.ConsumerGroup = "$Default";

    // Performance
    options.PrefetchCount = 300;
    options.MaxBatchSize = 100;

    // Processing
    options.StartingPosition = EventHubStartingPosition.Latest;

    // Security
    options.EnableEncryption = false;
    options.EncryptionProviderName = null;

    // Debugging
    options.EnableVerboseLogging = false;
    options.CustomProperties = new Dictionary<string, string>();
});

Storage Queues

services.Configure<AzureStorageQueueOptions>(options =>
{
    // Connection
    options.ConnectionString = null;
    options.StorageAccountUri = new Uri("https://mystorageaccount.queue.core.windows.net/");
    options.QueueName = "my-queue";

    // Processing
    options.MaxConcurrentMessages = 10;
    options.MaxMessages = 10;
    options.PollingInterval = TimeSpan.FromSeconds(1);
    options.VisibilityTimeout = TimeSpan.FromMinutes(5);
    options.EmptyQueueDelayMs = 1000;

    // Dead letter
    options.DeadLetterQueueName = null;
    options.MaxDequeueCount = 5;

    // Security
    options.EnableEncryption = false;
    options.EncryptionProviderName = null;

    // Debugging
    options.EnableVerboseLogging = false;
    options.CustomProperties = new Dictionary<string, string>();
});

See Also

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0-alpha.19 34 2/26/2026