A modern, attribute-driven .NET library for working with RabbitMQ. This library simplifies message publishing and consuming using a declarative approach with attributes and dependency injection.
- ✅ Attribute-Driven: Use simple attributes to define exchanges, routing keys, and message handlers
- ✅ Dependency Injection: Full DI support with automatic service registration
- ✅ Type-Safe Serialization: Built-in JSON serialization with support for complex objects
- ✅ Comprehensive Error Handling: Custom exceptions with actionable error messages
- ✅ Topology Management: Automatic exchange and queue declaration
- ✅ Clean Architecture: Minimal boilerplate, focus on your business logic
dotnet add package joerivanarkel.RabbitMQWrapperIn your Program.cs:
using joerivanarkel.RabbitMQWrapper.Extensions;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.ConfigureRabbitMQ(options =>
{
options.HostName = "localhost";
options.Port = 5672;
options.UserName = "admin";
options.Password = "password";
});
var provider = services.BuildServiceProvider();using joerivanarkel.RabbitMQWrapper.Attributes;
using joerivanarkel.RabbitMQWrapper.Core;
[QueueSender]
[Exchange("events")]
public class EventPublisher : QueueSenderBase
{
public EventPublisher(IServiceProvider serviceProvider)
: base(serviceProvider) { }
[RoutingKey("user.created")]
public void UserCreated(UserCreatedEvent evt)
{
SendMessage(evt);
}
[RoutingKey("order.placed")]
public void OrderPlaced(OrderPlacedEvent evt)
{
SendMessage(evt);
}
}using joerivanarkel.RabbitMQWrapper.Attributes;
using joerivanarkel.RabbitMQWrapper.Core;
[QueueReader]
[Exchange("events")]
public class EventConsumer : QueueReaderBase
{
public EventConsumer(IServiceProvider serviceProvider)
: base(serviceProvider) { }
[RoutingKeyFilter("user.created")]
public void OnUserCreated(UserCreatedEvent evt)
{
Console.WriteLine($"User created: {evt.UserId}");
}
[RoutingKeyFilter("order.*")]
public void OnOrderEvent(OrderEvent evt)
{
Console.WriteLine($"Order event: {evt.OrderId}");
}
}var publisher = provider.GetRequiredService<EventPublisher>();
var consumer = provider.GetRequiredService<EventConsumer>();
publisher.UserCreated(new UserCreatedEvent { UserId = "123" });
await Task.Delay(Timeout.Infinite); // Keep running[QueueSender]- Marks a class for auto-registration as a message sender[QueueReader]- Marks a class for auto-registration as a message consumer[Exchange("name")]- Specifies the exchange to use[RoutingKey("key")]- Defines the routing key for publishing (on methods)[RoutingKeyFilter("pattern")]- Defines routing patterns for consuming (on methods)
RabbitMQ supports wildcards in routing patterns:
*- Matches exactly one word#- Matches zero or more words
Examples:
[RoutingKeyFilter("user.*")] // user.created, user.updated
[RoutingKeyFilter("order.*.paid")] // order.us.paid, order.eu.paid
[RoutingKeyFilter("events.#")] // events, events.user, events.user.createdConsumer methods can accept:
- No parameters: Just notification, no data
- One parameter: Receives the deserialized message
string- Raw UTF8 text- Complex types - JSON deserialized objects
[RoutingKeyFilter("heartbeat")]
public void OnHeartbeat() { }
[RoutingKeyFilter("log.*")]
public void OnLog(string message) { }
[RoutingKeyFilter("user.*")]
public void OnUserEvent(UserEvent evt) { }The library provides detailed error messages organized by category:
- 1xxx - Connection errors
- 2xxx - Configuration errors
- 3xxx - Topology errors
- 4xxx - Serialization errors
- 5xxx - Messaging errors
try
{
publisher.SendEvent(evt);
}
catch (WrapperException ex)
{
Console.WriteLine($"Error {ex.ErrorCode}: {ex.Message}");
}For detailed error code documentation, see Error Codes Reference.
For more advanced usage including:
- Custom serializers
- Manual topology management
- Testing strategies
- Performance optimization
- Common patterns
See the Advanced Usage Guide.
See the demo projects for complete working examples:
joerivanarkel.RabbitMQWrapper.Demo.Senderjoerivanarkel.RabbitMQWrapper.Demo.Reader
MIT License - see LICENSE file for details
For issues, questions, or feature requests, please open an issue on GitHub.