Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

Hosting endpoints in .NET Aspire

.NET Aspire is a stack for developing distributed applications provided by Microsoft.

This sample shows a .NET Aspire AppHost project that orchestrates multiple NServiceBus endpoints, wiring up the required infrastructure pieces including a RabbitMQ broker and PostgreSQL database.

Running the sample

  1. Run the AspireDemo.AppHost project
  2. Open the .NET Aspire dashboard
  3. Review the metrics, traces, and structured log entries of each of the resources

Code walkthrough

AspireDemo.AppHost

The .NET Aspire orchestration project defines multiple resources and the relationships between them:

  • A RabbitMQ instance named transport
  • A PostgreSQL server named database
    • A database named shipping-db
    • An instance of pgweb to access the database
  • Four projects, each of which is an NServiceBus endpoint. All of these projects reference the transport resource.
    • clientui
    • billing
    • sales
    • shipping - also has a reference to the shipping-db resource
var builder = DistributedApplication.CreateBuilder(args);

var transport = builder.AddRabbitMQ("transport")
    .WithHealthCheck();

builder.AddProject<Projects.Billing>("billing")
    .WithReference(transport)
    .WaitFor(transport);

var sales = builder.AddProject<Projects.Sales>("sales")
    .WithReference(transport)
    .WaitFor(transport);

builder.AddProject<Projects.ClientUI>("clientui")
    .WithReference(transport)
    .WaitFor(transport)
    .WaitFor(sales);

var database = builder.AddPostgres("database")
    // NOTE: This is needed as the call to AddDatabase below
    // does not actually create the database
    .WithEnvironment("POSTGRES_DB", "shipping-db")
    .WithPgWeb();

var shippingDb = database.AddDatabase("shipping-db")
    .WithHealthCheck();

builder.AddProject<Projects.Shipping>("shipping")
    .WithReference(transport)
    .WaitFor(transport)
    .WithReference(shippingDb)
    .WaitFor(shippingDb);

builder.Build().Run();

AspireDemo.ServiceDefaults

The .NET Aspire service defaults project provides extension methods to configure application hosts in a standardized way. This project is referenced by all of the NServiceBus endpoint projects.

The OpenTelemetry configuration has been updated to include NServiceBus metrics and traces.

builder.Services.AddOpenTelemetry()
    .WithMetrics(metrics =>
    {
        metrics
            .AddMeter("NServiceBus.*")
            .AddAspNetCoreInstrumentation()
            .AddHttpClientInstrumentation()
            .AddRuntimeInstrumentation();
    })
    .WithTracing(tracing =>
    {
        tracing
            .AddSource("NServiceBus.*")
            .AddAspNetCoreInstrumentation()
            // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
            //.AddGrpcClientInstrumentation()
            .AddHttpClientInstrumentation();
    });

Endpoint projects

Each of the endpoint projects contain the same code to create an application host, apply the configuration from the ServiceDefaults project and enable OpenTelemetry on the NServiceBus endpoint.

var builder = Host.CreateApplicationBuilder();

var endpointConfiguration = new EndpointConfiguration("Shipping");
endpointConfiguration.EnableOpenTelemetry();

builder.AddServiceDefaults();

Each endpoint project retrieves the connection string for the RabbitMQ broker and configures NServiceBus to use it as a transport:

var connectionString = builder.Configuration.GetConnectionString("transport");
var transport = new RabbitMQTransport(RoutingTopology.Conventional(QueueType.Quorum), connectionString);

The Shipping endpoint additionally retrieves the connection string for the PostgreSQL database and configures NServiceBus to use it as a persistence:

var persistenceConnection = builder.Configuration.GetConnectionString("shipping-db");
var persistence = endpointConfiguration.UsePersistence<SqlPersistence>();
persistence.ConnectionBuilder(
    connectionBuilder: () =>
    {
        return new NpgsqlConnection(persistenceConnection);
    });

Finally, each endpoint enables NServiceBus installers. Every time the application host is run, the transport and persistence database are recreated and will not contain the queues and tables needed for the endpoints to run. Enabling installers allows NServiceBus to set up the assets that it needs at runtime.

endpointConfiguration.EnableInstallers();

If you're missing certain capabilities to use .NET Aspire with NServiceBus, share them and help shape the future of the platform.