NSY.MessageBus 1.0.1

dotnet add package NSY.MessageBus --version 1.0.1
                    
NuGet\Install-Package NSY.MessageBus -Version 1.0.1
                    
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="NSY.MessageBus" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NSY.MessageBus" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="NSY.MessageBus" />
                    
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 NSY.MessageBus --version 1.0.1
                    
#r "nuget: NSY.MessageBus, 1.0.1"
                    
#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 NSY.MessageBus@1.0.1
                    
#: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=NSY.MessageBus&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=NSY.MessageBus&version=1.0.1
                    
Install as a Cake Tool

NSY.MessageBus

A lightweight RabbitMQ message bus for .NET. Fan-out publish/subscribe with one durable queue per module, IConsumer<T> / ConsumeContext<T>, broker-enforced bounded retry + dead-lettering, and assembly-scanning registration.

Install

dotnet add package NSY.MessageBus

Concepts

  • Each message type is published to its own fanout exchange named after the type's full name.
  • Each consumer service declares one durable (quorum) queue and binds it to the exchanges of the messages it consumes.
  • Failures are nacked with requeue; the queue's x-delivery-limit retries up to MaxRetries, then RabbitMQ routes the message to <queue>.dead.
  • Delivery is at-least-once — make consumers idempotent.

Define a message and a consumer

Put message contracts in a shared assembly referenced by both publisher and consumer (the exchange name is the type's FullName, so it must match on both sides).

public record OrderPlaced(Guid OrderId, string Customer, decimal Total);

public class OrderPlacedConsumer : IConsumer<OrderPlaced>
{
    public async Task Consume(ConsumeContext<OrderPlaced> context)
    {
        var order = context.Message;
        // context.CancellationToken, context.MessageId, context.CorrelationId, context.ConversationId
    }
}

Register (single queue)

builder.Services.AddRabbitMqConsumers(
    queueName: "orders-service",
    configureOptions: o =>
    {
        o.HostName = "localhost";
        o.UserName = "guest";
        o.Password = "guest";
        // o.UseTls = true; o.Port = 5671;   // production
        // o.MaxRetries = 5; o.PrefetchCount = 20;
    },
    configureConsumers: c => c.AddConsumer<OrderPlaced, OrderPlacedConsumer>());

Register (bus + a queue per module)

Register the bus once (connection + publisher), then add a queue per module. This keeps publishing working even when a process has no consumers, and isolates each module's consumers to its own queue.

services.AddRabbitMqMessageBus(o => { o.HostName = "..."; /* ... */ });

services.AddRabbitMqConsumerQueue("ShipsHR.Candidates", c =>
{
    c.AddConsumer<CandidateCreated, CandidateCreatedConsumer>();
    // reflection overload for scanning: c.AddConsumer(messageType, consumerType);
});

Publish

Inject IMessagePublisher anywhere:

public class Orders(IMessagePublisher publisher)
{
    public Task Place(OrderPlaced e, CancellationToken ct) => publisher.Publish(e, ct);
}

The exchange is chosen from the message's runtime type, so publishing through a base/interface reference (IIntegratedEvent) still routes to the concrete event's exchange.

Cross-cutting hooks

Implement IConsumeResultHandler (register it yourself) to observe every consume outcome. Handlers are isolated — a throwing handler is logged and never breaks the ack/nack.

Options

Option Default Notes
HostName / Port / UserName / Password / VirtualHost localhost / 5672 / guest / guest / / Connection
UseTls / TlsServerName false / null AMQPS; use port 5671
MaxRetries 3 x-delivery-limit before dead-lettering
PrefetchCount 10 Unacked messages in flight

Requirements

  • .NET 10
  • RabbitMQ (quorum queues supported — RabbitMQ 3.8+)
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.1 138 7/9/2026
1.0.0 110 7/9/2026