ClearServiceBusInitializer 1.2.0
dotnet add package ClearServiceBusInitializer --version 1.2.0
NuGet\Install-Package ClearServiceBusInitializer -Version 1.2.0
<PackageReference Include="ClearServiceBusInitializer" Version="1.2.0" />
<PackageVersion Include="ClearServiceBusInitializer" Version="1.2.0" />
<PackageReference Include="ClearServiceBusInitializer" />
paket add ClearServiceBusInitializer --version 1.2.0
#r "nuget: ClearServiceBusInitializer, 1.2.0"
#:package ClearServiceBusInitializer@1.2.0
#addin nuget:?package=ClearServiceBusInitializer&version=1.2.0
#tool nuget:?package=ClearServiceBusInitializer&version=1.2.0
ClearServiceBusInitializer
A lightweight, code-first Azure Service Bus provisioning tool designed for small teams to manage Service Bus resources across different environments. It ensures that your Service Bus queues, topics, subscriptions, and rules are in place before your application starts�just have your Service Bus connection string ready.
Features
- ?? Code-First Configuration: Define your Service Bus resources using a fluent, strongly-typed API
- ?? Automatic Provisioning: Creates or updates Service Bus entities at application startup
- ?? Environment Agnostic: Works across development, staging, and production environments
- ??? Zero Infrastructure: No additional infrastructure tooling or manual setup required
- ?? Small Team Friendly: Perfect for teams without dedicated DevOps resources
- ?? Lightweight: Minimal dependencies and small footprint
- ?? Flexible Configuration: Support for queues, topics, subscriptions, and message filters
- ?? Type Safe: Strongly-typed configuration prevents runtime errors
Quick Start
1. Install the Package
dotnet add package ClearServiceBusInitializer
2. Define Your Service Bus Context
Create a class that implements IServiceBusContext
to define your messaging infrastructure:
public class MyAppServiceBusContext : IServiceBusContext
{
public string Name => "MyApp ServiceBus";
public void BuildServiceBusResource(ServiceBusResource serviceBusResource)
{
// Define queues
serviceBusResource.AddQueue("order-processing-queue");
serviceBusResource.AddQueue("payment-queue");
// Define topics with subscriptions and filters
serviceBusResource.AddTopic("order-events")
.AddSubscription("order-created-handler", "OrderCreated")
.AddSubscription("order-updated-handler", "OrderUpdated")
.AddSubscription("order-cancelled-handler", "OrderCancelled");
serviceBusResource.AddTopic("payment-events")
.AddSubscription("payment-processor", "PaymentStarted", "PaymentRetry")
.AddSubscription("notification-service", "PaymentCompleted", "PaymentFailed");
}
}
3. Register in Dependency Injection
In your Program.cs
, register the context using the extension method:
var builder = WebApplication.CreateBuilder(args);
// Register your Service Bus context
builder.Services.AddServiceBusContext<MyAppServiceBusContext>(
builder.Configuration.GetConnectionString("ServiceBus"));
var app = builder.Build();
// Provision Service Bus resources at startup
await app.CreateServiceBusResource();
app.Run();
That's it! Your Service Bus resources will be automatically created or updated when your application starts.
Enhanced Filtering (v1.2.0+)
Version 1.2.0 introduces enhanced filtering capabilities with direct Filter object support:
public class EnhancedServiceBusContext : IServiceBusContext
{
public string Name => "Enhanced ServiceBus";
public void BuildServiceBusResource(ServiceBusResource serviceBusResource)
{
var topic = serviceBusResource.AddTopic("order-events");
// Traditional approach (still supported)
topic.AddSubscription("simple-handler", "OrderCreated", "OrderUpdated");
// Enhanced filtering with custom SQL filters
var priorityFilter = Filter.Create("HighPriority", "Priority", 5);
var statusFilter = Filter.Create("ActiveStatus", "Status", "Active");
topic.AddSubscription("priority-handler", priorityFilter, statusFilter);
// Complex business rules
var vipFilter = Filter.Create("VIPCustomer", "CustomerTier", "VIP");
var highValueFilter = Filter.Create("HighValue", "Amount", 10000);
topic.AddSubscription("vip-processor", vipFilter, highValueFilter);
}
}
Advanced Configuration
Custom Queue Configuration
var queueOptions = new Queue.Option(
DefaultTimeToLive: TimeSpan.FromDays(7),
DuplicateDetectionWindow: TimeSpan.FromMinutes(10),
EnableBatchedOperations: true,
EnablePartitioning: false,
AutoDeleteOnIdle: TimeSpan.FromHours(24)
);
serviceBusResource.AddQueue("priority-queue", queueOptions);
Custom Topic Configuration
var topicOptions = new Topic.Option(
DefaultTimeToLive: TimeSpan.FromDays(14),
DuplicateDetectionWindow: TimeSpan.FromMinutes(5),
EnableBatchedOperations: true,
EnablePartitioning: true,
AutoDeleteOnIdle: null
);
serviceBusResource.AddTopic("events-topic", topicOptions);
Custom Subscription Configuration
var subscriptionOptions = new Subscription.Option(
DefaultTimeToLive: TimeSpan.FromDays(7),
DeadLetteringOnMessageExpiration: true,
LockDuration: TimeSpan.FromMinutes(5),
AutoDeleteOnIdle: TimeSpan.FromHours(2),
RequiresSession: true,
ForwardDeadLetterTo: "dead-letter-queue"
);
topic.AddSubscription("session-handler", subscriptionOptions, "SessionRequired");
Custom SQL Filters
// Using custom SQL expressions for complex filtering
subscription.Filters.Add(new Filter("CustomFilter", "MessageType = 'Order' AND Priority > 5"));
// New in v1.2.0: Helper methods for common filter patterns
var priorityFilter = Filter.Create("HighPriority", "Priority", 5);
var statusFilter = Filter.Create("ActiveStatus", "Status", "Active");
var labelFilter = Filter.CreateLabel("OrderCreated");
// Direct filter usage in subscription constructors
var subscription = new Subscription("priority-handler", priorityFilter, statusFilter);
// Enhanced topic configuration with complex filters
topic.AddSubscription("complex-handler", subscriptionOptions, priorityFilter, statusFilter);
// Fluent filter building
subscription.AddFilter(priorityFilter)
.AddFilter(statusFilter)
.AddLabelFilter("OrderCreated");
Static Resource Provisioning
For scenarios where you need to provision resources without dependency injection:
var serviceBusResource = new ServiceBusResource("MyApplication");
serviceBusResource.AddQueue("static-queue");
serviceBusResource.AddTopic("static-topic")
.AddSubscription("static-subscription", "StaticFilter");
await ServiceBusInitializer.CreateServiceBusResource(connectionString, serviceBusResource);
Entity Naming Conventions
The library automatically applies prefixes to entity names for consistency:
- Service Bus Resource:
sb-
prefix (e.g.,sb-myapp
) - Topics:
sbt-
prefix (e.g.,sbt-order-events
) - Queues:
sbq-
prefix (e.g.,sbq-payment-queue
) - Subscriptions:
sbs-
prefix (e.g.,sbs-order-handler
) - Filters/Rules:
sbsr-
prefix (e.g.,sbsr-ordercreated
)
Names are automatically:
- Converted to lowercase
- Spaces replaced with hyphens
- Trimmed of whitespace
- Prefixed if not already prefixed
Error Handling
The library includes specific exceptions for common scenarios:
try
{
await app.CreateServiceBusResource();
}
catch (ServiceBusAdministrationClientNotRegisteredException)
{
// Handle missing admin client registration
}
catch (ServiceBusContextNotRegisteredException)
{
// Handle missing context registration
}
Best Practices
1. Environment-Specific Contexts
Create different contexts for different environments:
public class DevelopmentServiceBusContext : IServiceBusContext
{
public string Name => "Dev Environment";
public void BuildServiceBusResource(ServiceBusResource resource)
{
// Minimal setup for development
resource.AddQueue("dev-test-queue");
}
}
public class ProductionServiceBusContext : IServiceBusContext
{
public string Name => "Production Environment";
public void BuildServiceBusResource(ServiceBusResource resource)
{
// Full production setup with custom configurations
var prodQueueOptions = new Queue.Option(
DefaultTimeToLive: TimeSpan.FromDays(14),
EnableBatchedOperations: true,
EnablePartitioning: true
);
resource.AddQueue("prod-orders", prodQueueOptions);
// ... more production resources
}
}
2. Modular Resource Definition
Break down large configurations into multiple methods:
public class MyServiceBusContext : IServiceBusContext
{
public string Name => "MyApp";
public void BuildServiceBusResource(ServiceBusResource resource)
{
ConfigureOrderResources(resource);
ConfigurePaymentResources(resource);
ConfigureNotificationResources(resource);
}
private void ConfigureOrderResources(ServiceBusResource resource)
{
resource.AddQueue("order-processing");
resource.AddTopic("order-events")
.AddSubscription("order-created-handler", "OrderCreated")
.AddSubscription("order-updated-handler", "OrderUpdated");
}
private void ConfigurePaymentResources(ServiceBusResource resource)
{
resource.AddQueue("payment-processing");
resource.AddTopic("payment-events")
.AddSubscription("payment-handler", "PaymentCompleted", "PaymentFailed");
}
private void ConfigureNotificationResources(ServiceBusResource resource)
{
resource.AddQueue("email-notifications");
resource.AddQueue("sms-notifications");
}
}
3. Configuration-Driven Setup
Use configuration to drive resource creation:
public class ConfigurableServiceBusContext : IServiceBusContext
{
private readonly IConfiguration _configuration;
public ConfigurableServiceBusContext(IConfiguration configuration)
{
_configuration = configuration;
}
public string Name => _configuration["ServiceBus:Name"] ?? "DefaultApp";
public void BuildServiceBusResource(ServiceBusResource resource)
{
var queues = _configuration.GetSection("ServiceBus:Queues").Get<string[]>() ?? [];
foreach (var queue in queues)
{
resource.AddQueue(queue);
}
var topics = _configuration.GetSection("ServiceBus:Topics").Get<TopicConfig[]>() ?? [];
foreach (var topicConfig in topics)
{
var topic = resource.AddTopic(topicConfig.Name);
foreach (var sub in topicConfig.Subscriptions)
{
topic.AddSubscription(sub.Name, sub.Filters);
}
}
}
}
Performance Considerations
- Startup Time: Resource provisioning happens at startup and may add 1-3 seconds depending on the number of entities
- Idempotent Operations: The library checks existing resources and only creates/updates what's necessary
- Batch Operations: Enable batched operations on queues and topics for better throughput
- Partitioning: Consider enabling partitioning for high-throughput scenarios
Troubleshooting
Common Issues
Connection String Issues
// Ensure your connection string is valid "Endpoint=sb://yournamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=yourkey"
Permission Issues
- Ensure your connection string has management permissions
- Verify the shared access key has "Manage" claims
Resource Already Exists
- The library handles existing resources gracefully
- It will update properties if they differ from the configuration
Debug Logging
Enable debug logging to see what resources are being created:
builder.Logging.AddConsole();
builder.Logging.SetMinimumLevel(LogLevel.Debug);
Examples
Check out the examples directory for complete sample applications demonstrating various usage patterns.
Contributing
Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- ?? Documentation
- ?? Report Issues
- ?? Discussions
Changelog
See CHANGELOG.md for a list of changes and version history.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | 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 was computed. 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. |
-
net9.0
- Azure.Messaging.ServiceBus (>= 7.19.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.5)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.