Oragon.RabbitMQ.Abstractions
1.0.0
Prefix Reserved
dotnet add package Oragon.RabbitMQ.Abstractions --version 1.0.0
NuGet\Install-Package Oragon.RabbitMQ.Abstractions -Version 1.0.0
<PackageReference Include="Oragon.RabbitMQ.Abstractions" Version="1.0.0" />
paket add Oragon.RabbitMQ.Abstractions --version 1.0.0
#r "nuget: Oragon.RabbitMQ.Abstractions, 1.0.0"
// Install Oragon.RabbitMQ.Abstractions as a Cake Addin #addin nuget:?package=Oragon.RabbitMQ.Abstractions&version=1.0.0 // Install Oragon.RabbitMQ.Abstractions as a Cake Tool #tool nuget:?package=Oragon.RabbitMQ.Abstractions&version=1.0.0
Oragon.RabbitMQ
Official Release
Others
Tech / Skill
Opinionated and Simplified Minimal APIs for Consuming Messages from RabbitMQ, Ensuring No Crucial Configurations Are Hidden.
What is Oragon.RabbitMQ?
Oragon.RabbitMQ is a Minimal API implementation for Consume RabbitMQ Queues.
Oragon.RabbitMQ provides everything you need to create resilient RabbitMQ consumers without the need to study numerous books and articles or introduce unknown risks to your environment.
Get Started
Add Consumer and Serializer packages
dotnet add package Oragon.RabbitMQ
dotnet add package Oragon.RabbitMQ.Serializer.SystemTextJson
Implement your service (with or without interface)
public class BusinessService
{
public async Task DoSomethingAsync(BusinessCommandOrEvent commandOrEvent)
{
... business core ...
}
}
Configuring Dependency Injection
Basic Setup
var builder = WebApplication.CreateBuilder(args); //or Host.CreateApplicationBuilder(args);
.../*your dependencies configuration*/...
builder.AddRabbitMQConsumer();
builder.Services.AddSingleton<BusinessService>();
builder.Services.AddSingleton<IAMQPSerializer>(sp => new SystemTextJsonAMQPSerializer(new System.Text.Json.JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults.General){ ... }));
Inject a valid IConnection on dependency injection
The consumer will use the dependency injection to get an valid instance of RabbitMQ.Client.IConnection. If you does not provider one, above you can see how to create a connection configuration.
...
builder.Services.AddSingleton<IConnectionFactory>(sp => new ConnectionFactory()
{
Uri = new Uri("amqp://rabbitmq:5672"),
DispatchConsumersAsync = true
});
builder.Services.AddSingleton(sp => sp.GetRequiredService<IConnectionFactory>().CreateConnectionAsync().GetAwaiter().GetResult());
...
If you are using .NET Aspire, you can use .NET Aspire with:
...
builder.AddRabbitMQClient("rabbitmq");
...
🎯 Map your Queue 🎯
To map your queue using this package, follow these steps:
Build the application: First, you need to build your application using the builder pattern. This initializes the application and prepares it for further configuration.
var app = builder.Build();
Map the queue: Next, map your queue to a specific service and command/event. This step involves configuring how the service will handle incoming messages from the queue.
app.MapQueue<BusinessService, BusinessCommandOrEvent>(config => config .WithDispatchInRootScope() // Use for singleton service .WithDispatchInChildScope() // Use for scoped service .WithAdapter((svc, msg) => svc.DoSomethingAsync(msg)) // Define how the service handles the message .WithQueueName("events") // Set the queue name .WithPrefetchCount(System.Environment.ProcessorCount * 16 * 10) // Set the prefetch count );
WithDispatchInRootScope()
: Use this for singleton services that should be instantiated once and shared across the application.WithDispatchInChildScope()
: Use this for scoped services that should be instantiated per request or per message.WithAdapter((svc, msg) => svc.DoSomethingAsync(msg))
: Define how the service handles the incoming message. This is where you specify the method to process the message.WithQueueName("events")
: Set the name of the queue from which the messages will be consumed.WithPrefetchCount(System.Environment.ProcessorCount * 16 * 10)
: Set the prefetch count to control how many messages the consumer can fetch at a time. This can help optimize performance.
Run the application: Finally, run the application to start processing messages from the queue.
app.Run();
Full Example
var builder = WebApplication.CreateBuilder(args);
builder.AddRabbitMQConsumer();
builder.Services.AddSingleton<BusinessService>();
builder.Services.AddSingleton<IAMQPSerializer>(sp => new SystemTextJsonAMQPSerializer(new System.Text.Json.JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults.General){ ... }));
builder.Services.AddSingleton<IConnectionFactory>(sp => new ConnectionFactory(){ Uri = new Uri("amqp://rabbitmq:5672"), DispatchConsumersAsync = true });
builder.Services.AddSingleton(sp => sp.GetRequiredService<IConnectionFactory>().CreateConnectionAsync().GetAwaiter().GetResult());
var app = builder.Build();
app.MapQueue<BusinessService, BusinessCommandOrEvent>(config => config
.WithDispatchInRootScope() // -> for singleton service
.WithDispatchInChildScope() // -> for scoped service
.WithAdapter((svc, msg) => svc.DoSomethingAsync(msg))
.WithQueueName("queue")
.WithPrefetchCount(System.Environment.ProcessorCount * 16 * 10)
);
app.Run();
Concepts
Decoupling Business Logic from Infrastructure
This approach is designed to decouple RabbitMQ consumers from business logic, ensuring that business code remains unaware of the queue consumption context.
The result is incredibly simple, decoupled, agnostic, more reusable, and highly testable code.
Opinionated Design: Why?
This consumer is focused on creating a resilient consumer using manual acknowledgments.
- The flow produces a
BasicReject
without requeue for serialization failures (e.g., incorrectly formatted messages), you will use dead-lettering to ensure these messages are not lost. - The flow produces a
BasicNack
with requeue for processing failures, allowing for message reprocessing. - Minimal API design style made without reflection
- Extensible with support for custom serializers and encoders
RabbitMQ Tracing com OpenTelemetry
Full support for OpenTelemetry on publishing or consuming RabbitMQ messages.
<img src="./docs/playground.gif">
Refactored to use RabbitMQ.Client 7x (with IChannel instead IModel)
Stages and Requirements for Launch
- Migrate Demo to Library Project
- Core: Queue Consumer
- Core: Rpc Queue Consumer
- Core: Support Keyed Services
- Core: Support of new design of RabbitMQ.Client
- Create Samples
- Review All SuppressMessageAttribute
- Create Docs
- Benchmarks
- Automate Badges
- Add SonarCloud
- Code Coverage > 80%
- Add CI/CD
- Add Unit Tests
- Add Integrated Tests with TestContainers
- Test CI/CD Flow: MyGet Alpha Packages with Symbols
- Test CI/CD Flow: MyGet Packages without Symbols
- Test CI/CD Flow: Nuget Packages without Symbols
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. |
-
net8.0
- Dawn.Guard (>= 1.12.0)
- OpenTelemetry.Extensions.Hosting (>= 1.9.0)
- RabbitMQ.Client (>= 7.0.0)
-
net9.0
- Dawn.Guard (>= 1.12.0)
- OpenTelemetry.Extensions.Hosting (>= 1.9.0)
- RabbitMQ.Client (>= 7.0.0)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Oragon.RabbitMQ.Abstractions:
Package | Downloads |
---|---|
Oragon.RabbitMQ
Provides a minimal API for RabbitMQ consumers, designed for simplicity and resilience. Enhance message handling with streamlined configuration and robust performance. |
|
Oragon.RabbitMQ.Serializer.NewtonsoftJson
Implements JSON serialization for RabbitMQ using Newtonsoft.Json. Easily serialize and deserialize messages for effective communication in RabbitMQ consumers. |
|
Oragon.RabbitMQ.Serializer.SystemTextJson
Implements JSON serialization for RabbitMQ using System.Text.Json. Leverage fast and modern serialization for efficient message handling in RabbitMQ consumers. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0 | 0 | 12/26/2024 |
0.0.11 | 97 | 12/17/2024 |
0.0.9-beta | 72 | 10/19/2024 |
0.0.8-beta | 46 | 8/2/2024 |
0.0.7-beta | 66 | 6/22/2024 |
0.0.6-beta | 67 | 6/6/2024 |
0.0.5-beta | 76 | 6/5/2024 |