This document describes the architecture and design of the ClearHostedEndpoint library.
ClearHostedEndpoint extends ClearHostedService from ClearHostedService to provide NServiceBus endpoint hosting capabilities. It inherits all the benefits of the base library while adding messaging-specific functionality.
IHostedService (Microsoft)
??? ClearHostedService (ClearHostedService)
??? ClearHostedEndpoint (ClearHostedEndpoint)
??? YourEndpoint (Your Application)
???????????????????????????????????????????????????????????????????
? Your Application ?
???????????????????????????????????????????????????????????????????
? OrderProcessingEndpoint : ClearHostedEndpoint ?
? ??? ConfigureTransport() - Define messaging transport ?
? ??? ConfigureEndpoint() - Additional endpoint config ?
? ??? Message Handlers - Business logic ?
???????????????????????????????????????????????????????????????????
? ClearHostedEndpoint ?
???????????????????????????????????????????????????????????????????
? ClearHostedEndpoint ?
? ??? CreateEndpointConfiguration() - Base NServiceBus setup ?
? ??? ConfigurePersistence() - SQL persistence ?
? ??? ConfigureRecoverability() - Retry policies ?
? ??? ConfigureSerialization() - JSON serialization ?
? ??? BuildServiceProviderAsync() - Start endpoint ?
???????????????????????????????????????????????????????????????????
? ClearHostedService ?
???????????????????????????????????????????????????????????????????
? ClearHostedService ?
? ??? StartAsync() / StopAsync() - Lifecycle management ?
? ??? Logger - Serilog integration ?
? ??? ServiceProvider - Isolated DI container ?
? ??? OnStartingAsync/OnStoppingAsync - Lifecycle hooks ?
???????????????????????????????????????????????????????????????????
? .NET Hosting ?
? IHostedService, IServiceCollection, IHost ?
???????????????????????????????????????????????????????????????????
The core class that bridges ClearHostedService with NServiceBus:
| Method | Responsibility |
|---|---|
CreateEndpointConfiguration() |
Creates NServiceBus configuration with common settings |
ConfigureTransport() |
Abstract - Must be implemented to specify transport |
ConfigureEndpoint() |
Optional additional endpoint configuration |
ConfigureEndpointAsync() |
Optional async endpoint configuration |
ConfigureSerialization() |
Sets up JSON serialization (overridable) |
ConfigurePersistence() |
Configures SQL persistence or LearningPersistence |
ConfigureRecoverability() |
Sets up retry policies |
BuildServiceProviderAsync() |
Starts the endpoint and returns service provider |
OnStoppingAsync() |
Gracefully stops the NServiceBus endpoint |
Configuration class for endpoint behavior:
- Endpoint naming and queue configuration
- Concurrency and retry settings
- Outbox configuration for exactly-once processing
Configuration class for SQL Server persistence:
- Connection string and schema settings
- Saga and subscription storage configuration
- Table prefix customization
Host.StartAsync()
?
?
ClearHostedService.StartAsync()
?
??? CreateServiceCollection()
??? RegisterDependencyInjection()
??? ConfigureLogging()
?
?
ClearHostedEndpoint.BuildServiceProviderAsync()
?
??? CreateEndpointConfiguration()
? ??? Set endpoint name
? ??? Enable installers (if configured)
? ??? Configure error/audit queues
? ??? Set concurrency limit
?
??? ConfigureEndpoint() ? Override for custom config
??? ConfigureTransport() ? MUST override (abstract)
??? ConfigureSerialization() ? Override for custom serializer
??? ConfigurePersistence() ? Override for custom persistence
??? ConfigureRecoverability() ? Override for custom retry policy
??? RegisterComponents() ? Inject DI services
??? ConfigureEndpointAsync() ? Override for async config
?
?
Endpoint.Start() ? NServiceBus starts
?
?
OnStartingAsync() ? Lifecycle hook
?
?
ExecuteAsync() ? Waits for cancellation
?
? (on shutdown)
OnStoppingAsync()
?
??? EndpointInstance.Stop() ? Graceful NServiceBus shutdown
?
?
Dispose()
The ConfigureTransport() method is abstract, requiring derived classes to specify their transport:
// RabbitMQ Example
protected override void ConfigureTransport(EndpointConfiguration endpointConfiguration)
{
var transport = endpointConfiguration.UseTransport<RabbitMQTransport>();
transport.ConnectionString("host=rabbitmq;username=guest;password=guest");
var routing = transport.Routing();
routing.RouteToEndpoint(typeof(ProcessPayment), "PaymentService");
}
// Azure Service Bus Example
protected override void ConfigureTransport(EndpointConfiguration endpointConfiguration)
{
var transport = endpointConfiguration.UseTransport<AzureServiceBusTransport>();
transport.ConnectionString(Environment.GetEnvironmentVariable("ASB_CONNECTION"));
}
// Learning Transport (Development)
protected override void ConfigureTransport(EndpointConfiguration endpointConfiguration)
{
var transport = endpointConfiguration.UseTransport<LearningTransport>();
transport.StorageDirectory(Path.Combine(Path.GetTempPath(), "learning-transport"));
}The library supports two persistence modes:
When SqlPersistenceOptions is null, the library uses in-memory learning persistence:
// No SqlPersistenceOptions = LearningPersistence
protected override SqlPersistenceOptions? SqlPersistenceOptions => null;When SqlPersistenceOptions is provided:
protected override SqlPersistenceOptions? SqlPersistenceOptions => new()
{
ConnectionString = "Server=.;Database=Sagas;Integrated Security=true",
Schema = "nsb",
EnableSagaPersistence = true,
EnableSubscriptionStorage = true
};The library wraps NServiceBus startup failures in EndpointConfigurationException:
try
{
_endpointInstance = await Endpoint.Start(endpointConfiguration, cancellationToken);
}
catch (Exception ex)
{
throw new EndpointConfigurationException(
$"Failed to start NServiceBus endpoint '{EffectiveEndpointName}'.", ex);
}-
Abstract Transport Configuration: Forces explicit transport choice rather than providing a default that might not be suitable.
-
SQL Server Default: For SQL persistence, defaults to SQL Server via
Microsoft.Data.SqlClient, butCreateDbConnection()can be overridden for other databases. -
JSON Serialization: Uses
SystemJsonSerializerby default for modern .NET compatibility. -
Isolated Service Provider: Each endpoint has its own DI container, inherited from ClearHostedService.
-
Graceful Shutdown: Properly stops NServiceBus endpoint in
OnStoppingAsync()before disposal.