AwadyLab.Mediator.RabbitMQ
1.7.0
See the version list below for details.
dotnet add package AwadyLab.Mediator.RabbitMQ --version 1.7.0
NuGet\Install-Package AwadyLab.Mediator.RabbitMQ -Version 1.7.0
<PackageReference Include="AwadyLab.Mediator.RabbitMQ" Version="1.7.0" />
<PackageVersion Include="AwadyLab.Mediator.RabbitMQ" Version="1.7.0" />
<PackageReference Include="AwadyLab.Mediator.RabbitMQ" />
paket add AwadyLab.Mediator.RabbitMQ --version 1.7.0
#r "nuget: AwadyLab.Mediator.RabbitMQ, 1.7.0"
#:package AwadyLab.Mediator.RabbitMQ@1.7.0
#addin nuget:?package=AwadyLab.Mediator.RabbitMQ&version=1.7.0
#tool nuget:?package=AwadyLab.Mediator.RabbitMQ&version=1.7.0
AwadyLab.Mediator.RabbitMQ
RabbitMQ queue and distributed pub/sub broker transport for AwadyLab.Mediator.
Overview
AwadyLab.Mediator.RabbitMQ integrates RabbitMQ with AwadyLab.Mediator, supporting two distinct messaging topologies over a single shared connection:
flowchart TD
Mediator{{"AwadyLab.Mediator"}}
Mediator -->|"Delivery = Queue"| QMode["Queue Mode<br/>(RabbitMqMessageQueue)"]
Mediator -->|"Delivery = Broker"| BMode["Broker Mode<br/>(RabbitMqBroker)"]
QMode --> SingleQueue[("Durable Service Queue<br/>x-dead-letter-exchange")]
BMode --> TopicEx["Topic / Fanout Exchange"]
SingleQueue --> Pump["Internal Queue Pump"]
TopicEx --> SubQ1[("Consumer Queue A")]
TopicEx --> SubQ2[("Consumer Queue B")]
SubQ1 --> H1{{"IExternalNotificationHandler<>"}}
SubQ2 --> H2{{"IExternalNotificationHandler<>"}}
- Queue Mode (
NotificationDelivery.Queue): Replaces the default in-memory channel queue with a durable RabbitMQ queue (RabbitMqMessageQueue). Enqueued messages survive application restarts and are processed by local worker loops. - Broker Mode (
NotificationDelivery.Broker): Full cross-service pub/sub messaging across independent microservices (RabbitMqBrokerandRabbitMqSubscription) with automatic topology declaration, publisher confirms, and reconnect recovery.
You can enable Queue Mode, Broker Mode, or Both simultaneously over a single AMQP connection.
Features & Reliability
- Publisher Confirms: Enabled by default (
PublisherConfirms = true). Publishes synchronously await RabbitMQ broker acknowledgment before returning. - Channel Pooling: Publishes share a managed pool of channels (
PublishChannelPoolSize = 8by default) to eliminate channel churn and maximize throughput. - Resilient Reconnections: Automatically detects network loss or broker restarts, restores connection, and recreates subscriptions without dropping workers.
- Header Sanitization: Prevents CRLF injection and Unicode directional override vulnerabilities across envelope headers.
- Dead-Letter Support: RabbitMQ rejected messages route to
DeadLetterExchange, while exhausted retry attempts route toIDeadLetterSink.
Installation
dotnet add package AwadyLab.Mediator.RabbitMQ
Quickstart
1. Register in DI (Program.cs)
using AwadyLab.Mediator;
using AwadyLab.Mediator.RabbitMQ;
using AwadyLab.Mediator.RabbitMQ.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMediator([typeof(Program).Assembly], options =>
{
options.UseRabbitMq(new RabbitMqOptions
{
ConnectionString = "amqp://guest:guest@localhost:5672/",
// 1. Enable Broker Pub/Sub Mode
Broker = new RabbitMqBrokerOptions
{
Prefetch = 20,
DeadLetterExchange = "dlx.events"
},
// 2. (Optional) Enable Durable Queue Mode for local queue delivery
Queue = new RabbitMqQueueOptions
{
QueueName = "orders-service-queue",
Prefetch = 10
}
});
});
var app = builder.Build();
Broker Mode (Cross-Service Pub/Sub)
In Broker mode, events published with NotificationDelivery.Broker are serialized and broadcast to an exchange. Subscribing microservices consume events through their own durable queues.
1. Define Notification & Topology
Implement IExternalNotificationDefinition<T> to declare the exchange contract:
using AwadyLab.Mediator.Abstraction;
using AwadyLab.Mediator.Abstraction.Messaging;
using AwadyLab.Mediator.Models.Options;
using AwadyLab.Mediator.RabbitMQ;
// Domain event contract
public record OrderPlacedNotification(Guid OrderId, decimal Total) : INotification;
// Topology definition (exchange contract)
public sealed class OrderPlacedDefinition : IExternalNotificationDefinition<OrderPlacedNotification>
{
public void Define(ExternalNotificationOptions options)
{
// Declares topic exchange and optional routing rules
options.RabbitMq.Exchange = "orders.events";
options.RabbitMq.ExchangeType = "topic";
options.RabbitMq.RoutingKey = "orders.placed";
}
}
2. Implement External Subscriber Handler
Consumers implement IExternalNotificationHandler<T> and specify a static QueueName:
using AwadyLab.Mediator.Abstraction.Messaging;
using AwadyLab.Mediator.Models.Options;
[ExternalSubscription(Prefetch = 25, MaxRetries = 3)]
public class BillingServiceHandler(IBillingService billing)
: IExternalNotificationHandler<OrderPlacedNotification>
{
// Required: Identifies the subscription queue bound to the exchange
public static string QueueName => "billing-service.orders";
public async Task Handle(OrderPlacedNotification notification, CancellationToken ct)
{
await billing.GenerateInvoiceAsync(notification.OrderId, notification.Total, ct);
}
}
3. Publishing to the Broker
await mediator.Publish(new OrderPlacedNotification(orderId, 250m), options =>
{
options.Delivery = NotificationDelivery.Broker;
// Optional: Set per-message RabbitMQ publish overrides
options.RabbitMq.RoutingKey = "orders.placed.eu";
options.RabbitMq.Priority = 2;
options.RabbitMq.Expiration = TimeSpan.FromMinutes(30);
});
Queue Mode (Durable In-Process Channel)
When RabbitMqOptions.Queue is configured, NotificationDelivery.Queue routes envelopes through a durable RabbitMQ queue instead of an in-memory channel:
await mediator.Publish(new OrderPlacedNotification(orderId, 250m), options =>
{
options.Delivery = NotificationDelivery.Queue;
});
- Survives service restarts.
- Drained by the mediator's background
NotificationQueuePumpworkers with exponential backoff retries.
Options Reference
RabbitMqOptions
| Option | Type | Default | Description |
|---|---|---|---|
ConnectionString |
string |
(Required) | AMQP URI (amqp:// or amqps://). Validated at startup. |
PublisherConfirms |
bool |
true |
Requests publisher confirmation for every publish. |
PublishChannelPoolSize |
int |
8 |
Size of the pooled channels for concurrent publishing. |
ReconnectDelay |
TimeSpan |
5s |
Wait duration between connection retry attempts. |
Broker |
RabbitMqBrokerOptions? |
null |
Enables cross-service pub/sub broker mode when configured. |
Queue |
RabbitMqQueueOptions? |
null |
Enables durable queue mode for NotificationDelivery.Queue. |
RabbitMqBrokerOptions
| Option | Type | Default | Description |
|---|---|---|---|
Prefetch |
ushort |
10 |
Default prefetch count for consumer subscriptions. |
DeadLetterExchange |
string? |
null |
Sets x-dead-letter-exchange on declared subscription queues. |
RabbitMqQueueOptions
| Option | Type | Default | Description |
|---|---|---|---|
QueueName |
string? |
null |
Custom name for the queue (auto-generated if omitted). |
Durable |
bool |
true |
Whether the queue survives broker restarts. |
Prefetch |
ushort |
10 |
Consumer prefetch count for queue pump workers. |
DeadLetterQueue |
string? |
null |
DLQ routing for unhandled rejected messages. |
License
Package by Mohamed Elawady
Copyright (c) Mohamed Elawady. All rights reserved.
This software is closed source and proprietary. Subject to the terms below,
you are granted a free, worldwide, non-exclusive license to:
- Use this software, in source or compiled (NuGet package) form, in your
own applications, including commercial applications, at no charge.
You may NOT:
- Redistribute, sublicense, sell, or publish this software (or any
modified version of it) as a standalone product, library, or package,
including republishing it under a different name on NuGet.org or any
other package repository.
- Reverse engineer, decompile, or disassemble the compiled package except
to the extent applicable law expressly permits this despite this
limitation.
- Remove or alter any copyright, trademark, or other proprietary notices.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
| 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
- AwadyLab.Mediator (>= 1.7.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- RabbitMQ.Client (>= 7.1.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.