Commify.Titan.API.RabbitMQ 0.13.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Commify.Titan.API.RabbitMQ --version 0.13.0
                    
NuGet\Install-Package Commify.Titan.API.RabbitMQ -Version 0.13.0
                    
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="Commify.Titan.API.RabbitMQ" Version="0.13.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Commify.Titan.API.RabbitMQ" Version="0.13.0" />
                    
Directory.Packages.props
<PackageReference Include="Commify.Titan.API.RabbitMQ" />
                    
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 Commify.Titan.API.RabbitMQ --version 0.13.0
                    
#r "nuget: Commify.Titan.API.RabbitMQ, 0.13.0"
                    
#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 Commify.Titan.API.RabbitMQ@0.13.0
                    
#: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=Commify.Titan.API.RabbitMQ&version=0.13.0
                    
Install as a Cake Addin
#tool nuget:?package=Commify.Titan.API.RabbitMQ&version=0.13.0
                    
Install as a Cake Tool

Commify.Titan.API.RabbitMQ

Self-contained NuGet package that adds RabbitMQ messaging to any .NET 10 application. Supports event publishing/consuming with zero configuration, custom message routing, outbox pattern with PostgreSQL, and dead letter queues.

Contact: Titan API Team

Configuration

Add the following to appsettings.json:

{
  "TitanCommunication": {
    "RabbitMQ": {
      "Host": "host",
      "Port": 5672,
      "BasicCredentials": {
        "Username": "username",
        "Password": "password"
      }
    }
  }
}
  • BasicCredentials enables basic authentication. When omitted, the package falls back to AAD token authentication.

Environment variables

Variable Required Description
K8S_POD_NAME Yes Used to generate unique, auto-deleting queue names for consumers that don't specify a QueueName.

Initialization

Register the Titan framework, then initialize RabbitMQ connections at startup:

var builder = Host.CreateApplicationBuilder(args);

builder.Services
    .AddTitanFramework(builder.Configuration);

// Register publishers and consumers (see sections below)

var app = builder.Build();

await app.InitializeAsync();                          // opens RabbitMQ connections
await app.ApplyEventPublisherMigrations();           // applies outbox EF Core migrations (only if using outbox)

await app.RunAsync();

Publishing

Event publishing

RegisterEventPublisher uses the shared event defaults (RabbitMqEventDefaults) and the outbox pattern. No manual settings required.

services.RegisterEventPublisher<LoginEventData>(
    context.Configuration,
    context.Configuration.GetConnectionString("AppDb")!);

Inject IOutboxMessagePublisher<T> and call SaveChangesAsync to transactionally save the message alongside your domain changes:

public class LoginService(
    IOutboxMessagePublisher<LoginEventData> publisher,
    IDbContextFactory<AppDbContext> dbContextFactory)
{
    public async Task HandleLoginAsync(LoginEventData data, CancellationToken ct)
    {
        var dbContext = await dbContextFactory.CreateDbContextAsync(ct);

        QueueMessage<LoginEventData> message = new()
        {
            Id = Guid.NewGuid(),
            Headers = new QueueHeaders
            {
                CorrelationId = Guid.NewGuid(),
                Source = "LoginService",
                Type = "LoginEventData",
                OccurredAt = DateTimeOffset.UtcNow
            },
            Payload = data
        };

        await publisher.SaveChangesAsync(dbContext, message, ct);
    }
}

A background service polls the outbox and publishes pending messages with exponential backoff.

Message publishing

RegisterMessagePublisher registers an IMessagePublisher<T> with custom exchange settings. Available in two overloads:

// Without IServiceProvider
services.RegisterMessagePublisher<Message>(context.Configuration, ()
    => new()
    {
        VirtualHost = "API",
        ExchangeName = "ex.mock",
        ExchangeType = "fanout"
    });

// With IServiceProvider
services.RegisterMessagePublisher<Message>(context.Configuration, (sp)
    => new()
    {
        VirtualHost = "API",
        ExchangeName = "ex.mock",
        ExchangeType = "fanout"
    });

Inject IMessagePublisher<T> and call PublishAsync:

await messagePublisher.PublishAsync(queueMessage, customTrace, cancellationToken);

Outbox message publishing

RegisterMessagePublisherWithOutbox combines custom exchange settings with the PostgreSQL outbox:

// Without IServiceProvider
services.RegisterMessagePublisherWithOutbox<Message>(
    context.Configuration,
    dbConnectionString,
    () => new()
    {
        VirtualHost = "API",
        ExchangeName = "ex.custom",
        ExchangeType = "direct",
        RoutingKey = "my.routing.key"
    });

// With IServiceProvider
services.RegisterMessagePublisherWithOutbox<Message>(
    context.Configuration,
    dbConnectionString,
    (sp) => new()
    {
        VirtualHost = "API",
        ExchangeName = "ex.custom",
        ExchangeType = "direct",
        RoutingKey = "my.routing.key"
    });

Inject IOutboxMessagePublisher<T> and use SaveChangesAsync.

Consuming

Event consuming

RegisterEventConsumer uses the shared event defaults (RabbitMqEventDefaults). No manual settings required.

services.RegisterEventConsumer<LoginEventData, LoginEventHandler>(context.Configuration);

Implement IMessageConsumer<T>:

public class LoginEventHandler : IMessageConsumer<LoginEventData>
{
    public async Task HandleMessageAsync(
        QueueMessage<LoginEventData> message,
        RabbitMQConsumerTrace customTrace,
        CancellationToken cancellationToken)
    {
        // Process the message
    }

    public async Task HandleExceptionAsync(
        Exception exception,
        RabbitMQConsumerTrace customTrace,
        CancellationToken cancellationToken)
    {
        // Handle consumer errors
    }
}

Message consuming

RegisterMessageConsumer requires custom settings. Available in two overloads:

// Without IServiceProvider
services.RegisterMessageConsumer<LoginEventData, LoginEventHandler>(context.Configuration, ()
    => new()
    {
        VirtualHost = "API",
        ExchangeNameToBind = "ex.events",
        ExchangeType = "fanout",
        QueueName = "q.my-service.login-events",   // optional, auto-generated from K8S_POD_NAME if omitted
        RoutingKey = "login.#"                       // optional
    });

// With IServiceProvider
services.RegisterMessageConsumer<LoginEventData, LoginEventHandler>(context.Configuration, (sp)
    => new()
    {
        VirtualHost = "API",
        ExchangeNameToBind = "ex.events",
        ExchangeType = "fanout"
    });

When QueueName is omitted, a queue is auto-created using K8S_POD_NAME and deleted when the application stops.

Dead letter queues

Failed messages can be routed to a dead letter queue by setting three properties on RabbitMqConsumerSettings:

Setting Description
DeadLetterQueueName Queue where failed messages are stored
DeadLetterExchangeName Exchange that routes to the dead letter queue
DeadLetterRoutingKey Routing key for dead letter message routing

All three must be set, or none. Partial configuration throws an ArgumentNullException at startup.

services.RegisterMessageConsumer<LoginEventData, LoginEventHandler>(context.Configuration, ()
    => new()
    {
        VirtualHost = "API",
        ExchangeNameToBind = "ex.events",
        ExchangeType = "fanout",
        DeadLetterQueueName = "q.dlx.login-events",
        DeadLetterExchangeName = "ex.dlx.events",
        DeadLetterRoutingKey = "dlx.login-events"
    });

When configured, any unhandled exception in HandleMessageAsync causes the message to be published to the dead letter exchange with the original headers plus a DeadLetterReason header containing the exception message. Dead letter exchanges always use the topic exchange type.

Custom implementation

For full control over publishing and consuming, use RegisterRabbitMQMessaging to register only the connection management layer:

services.RegisterRabbitMQMessaging(context.Configuration);

This registers a singleton IConnectionManagement that you can inject to create channels directly:

var channel = await connectionManagement.CreateChannelAsync("API", customTrace, cancellationToken);

Key types

Type Description
QueueMessage<T> Message envelope containing Id, Headers, and Payload
QueueHeaders Message metadata: CorrelationId, Source, Type, OccurredAt, TestScenario, DeadLetterReason
IMessagePublisher<T> Publishes messages directly to RabbitMQ
IOutboxMessagePublisher<T> Saves messages to a PostgreSQL outbox for reliable delivery
IMessageConsumer<T> Consumer contract with HandleMessageAsync and HandleExceptionAsync
IDeadLetterPublisher<T> Publishes failed messages to a dead letter exchange
IConnectionManagement Low-level channel creation per virtual host
RabbitMqPublisherSettings Publisher config: VirtualHost, ExchangeName, ExchangeType, RoutingKey
RabbitMqConsumerSettings Consumer config: VirtualHost, ExchangeNameToBind, ExchangeType, QueueName, RoutingKey, dead letter settings
RabbitMqEventDefaults Shared constants for event routing: ExchangeName, ExchangeType, VirtualHost
Product Compatible and additional computed target framework versions.
.NET 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
1.0.6 67 3/10/2026
1.0.5 95 3/9/2026
1.0.4 75 3/8/2026
1.0.3 71 3/7/2026
1.0.2 71 3/7/2026
1.0.1 71 3/6/2026
1.0.0 66 3/6/2026
0.16.0 69 3/6/2026
0.15.0 69 3/6/2026
0.14.0 72 3/5/2026
0.13.0 67 3/5/2026
0.8.0 68 3/5/2026
0.7.0 68 3/5/2026
0.6.0 88 3/2/2026
0.5.0 87 2/24/2026
0.1.0 110 2/20/2026