NSY.MessageBus
1.0.1
dotnet add package NSY.MessageBus --version 1.0.1
NuGet\Install-Package NSY.MessageBus -Version 1.0.1
<PackageReference Include="NSY.MessageBus" Version="1.0.1" />
<PackageVersion Include="NSY.MessageBus" Version="1.0.1" />
<PackageReference Include="NSY.MessageBus" />
paket add NSY.MessageBus --version 1.0.1
#r "nuget: NSY.MessageBus, 1.0.1"
#:package NSY.MessageBus@1.0.1
#addin nuget:?package=NSY.MessageBus&version=1.0.1
#tool nuget:?package=NSY.MessageBus&version=1.0.1
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-limitretries up toMaxRetries, 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 | Versions 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. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.9)
- RabbitMQ.Client (>= 7.2.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.