DependencyInjection - velviagris/NanoRabbit GitHub Wiki
- Catalog
NanoRabbit is designed as a easy-to-register library.
NanoRabbit is a Lightweight RabbitMQ .NET 3rd party library for .NET 6 and up, which is not including the management API of RabbitMQ, so you should deploy your own RabbitMQ and configure all the Users, Virtual Hosts, Exchanges, Queues before you start using NanoRabbit.
The only thing you need to do is inject NanoRabbit in Program.cs follow the below steps:
- Register
RabbitHelper - Add
RabbitConsumerto RabbitHelper
Inject RabbitHelper in Program.cs by calling AddRabbitHelper(this IServiceCollection services, Action\<RabbitConfigurationBuilder> builder), which is used to add a singleton service of the type specified in IRabbitHelper with a factory specified in implementationFactory to the specified Microsoft.Extensions.DependencyInjection.IServiceCollection.
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddRabbitHelper(builder =>
{
builder.SetHostName("localhost")
.SetPort(5672)
.SetVirtualHost("/")
.SetUserName("admin")
.SetPassword("admin")
.AddProducerOption(producer =>
{
producer.ProducerName = "FooProducer";
producer.ExchangeName = "amq.topic";
producer.RoutingKey = "foo.key";
producer.Type = ExchangeType.Topic;
})
.AddConsumerOption(consumer =>
{
consumer.ConsumerName = "FooConsumer";
consumer.QueueName = "foo-queue";
consumer.HandlerName = nameof(FooQueueHandler);
});
})As the sample code above, we added a consumer option, so we have to add a RabbitConsumer to RabbitHelper to use the consumer option.
NanoRabbit provides a class named DefaultAsyncMessageHandler, which is a default implementation of IMessageHandler, you can simply inherit it and override the HandleMessageAsync(string message) to handle the messages in queue.
Sample code:
public class FooQueueHandler : IAsyncMessageHandler
{
public async Task HandleMessageAsync(byte[] messageBody, string? routingKey = null, string? correlationId = null)
{
var message = Encoding.UTF8.GetString(messageBody);
Console.WriteLine($"[x] Received from foo-queue: {message}");
await Task.Delay(1000);
Console.WriteLine("[x] Done");
}
}Then we could add a RabbitConsumer to RabbitHelper:
builder.Services.AddRabbitHandler<FooQueueHandler>()
.AddRabbitConsumerService();After that, build the host and run, and we can start to subscribe the queue.
using IHost host = builder.Build();
host.Run();After injection, you can use RabbitHelper in the project, for example, create a BackgroundService, named "PublishService.cs":
public class PublishService : BackgroundService
{
private readonly ILogger<PublishService> _logger;
private readonly IRabbitHelper _rabbitHelper;
public PublishService(ILogger<PublishService> logger, IRabbitHelper rabbitHelper)
{
_logger = logger;
_rabbitHelper = rabbitHelper;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Testing PublishService");
while (!stoppingToken.IsCancellationRequested)
{
await _rabbitHelper.PublishAsync("FooProducer", "Hello from FooProducer.");
await Task.Delay(1000, stoppingToken);
}
}
}Then, add this BackgroundService at Program.cs:
builder.Services.AddHostedService<PublishService>();There are some advenced usage of NanoRabbit:
- Add Keyed Singleton Service (For multiple connections)
- Add RabbitHelper by reading configs.
In some cases, you want to inject more than one RabbitMQ connections in your project, which is possible by calling AddKeyedRabbitHelper(this IServiceCollection services, string key, Action<RabbitConfigurationBuilder> builders). This is a new feature, which is supported from .NET 7 on.
var builder = Host.CreateApplicationBuilder();
builder.Services.AddKeyedRabbitHelper("DefaultRabbitHelper", builder =>
{
builder.SetHostName("localhost")
.SetPort(5672)
.SetVirtualHost("/")
.SetUserName("admin")
.SetPassword("admin")
.AddProducerOption(producer =>
{
producer.ProducerName = "FooProducer";
producer.ExchangeName = "amq.topic";
producer.RoutingKey = "foo.key";
producer.Type = ExchangeType.Topic;
})
.AddConsumerOption(consumer =>
{
consumer.ConsumerName = "DefaultFooConsumer";
consumer.QueueName = "foo-queue";
consumer.HandlerName = nameof(DefaultFooConsumer);
});
}).AddRabbitHandler<DefaultFooQueueConsumer>().AddKeyedRabbitConsumerService("DefaultRabbitHelper");
builder.Services.AddKeyedRabbitHelper("TestRabbitHelper", builder =>
{
builder.SetHostName("localhost")
.SetPort(5672)
.SetVirtualHost("test")
.SetUserName("admin")
.SetPassword("admin")
.AddProducerOption(producer =>
{
producer.ProducerName = "FooProducer";
producer.ExchangeName = "amq.topic";
producer.RoutingKey = "foo.key";
producer.Type = ExchangeType.Topic;
})
.AddConsumerOption(consumer =>
{
consumer.ConsumerName = "TestFooConsumer";
consumer.QueueName = "foo-queue";
consumer.HandlerName = nameof(TestFooQueueConsumer);
});
}).AddRabbitHandler<TestFooQueueConsumer>().AddKeyedRabbitConsumerService("TestRabbitHelper");If you want to add RabbitConsumer to the Keyed RabbitHelper, you should use AddRabbitHandler<THandler>(this IServiceCollection services) function, the handler should name as the same with HandlerName in ConsumerOptions.
NanoRabbit provides a function (GetRabbitHelper(this IServiceProvider serviceProvider, string key)) to get RabbitHelper service by key, call it in your code:
public class DefaultPublishService : BackgroundService
{
private readonly ILogger<DefaultPublishService> _logger;
private readonly IRabbitHelper _rabbitHelper;
public DefaultPublishService(ILogger<DefaultPublishService> logger, IServiceProvider serviceProvider)
{
_logger = logger;
_rabbitHelper = serviceProvider.GetRabbitHelper("DefaultRabbitHelper");
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Testing DefaultPublishService");
while (!stoppingToken.IsCancellationRequested)
{
await _rabbitHelper.PublishAsync("FooProducer", "Hello from default publish service.");
await Task.Delay(1000, stoppingToken);
}
}
}There is a way to add RabbitHelper with less code in Program.cs, write your configs of NanoRabbit in appsettings.json, and inject RabbitHelper by calling AddRabbitHelperFromAppSettings<TRabbitConfiguration>(this IServiceCollection services, IConfiguration configuration).
According to RabbitConfiguration predefined in NanoRabbit, we should add the config with the same format in appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"RabbitConfiguration": {
"HostName": "localhost",
"Port": 5672,
"UserName": "admin",
"Password": "admin",
"VirtualHost": "/",
"Producers": [
{
"ProducerName": "FooProducer",
"ExchangeName": "amq.topic",
"RoutingKey": "foo.key",
"Type": "topic"
},
{
"ProducerName": "BarProducer",
"ExchangeName": "amq.direct",
"RoutingKey": "bar.key",
"Type": "direct"
}
],
"Consumers": [
{
"ConsumerName": "FooConsumer",
"QueueName": "foo-queue",
"PrefetchCount": 3,
"HandlerName": "FooQueueHandler"
},
{
"ConsumerName": "BarConsumer",
"QueueName": "bar-queue",
"PrefetchCount": 2,
"HandlerName": "BarQueueHandler"
}
]
}
}Add RabbitHelper in Program.cs:
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddRabbitHelperFromAppSettings<FooConfiguration>(builder.Configuration)
.AddRabbitConsumer<FooQueueHandler>()
.AddRabbitConsumer<BarQueueHandler>()
.AddRabbitConsumerServiceFromAppSettings<FooConfiguration>(builder.Configuration);You can register multiple connections by using new feature (AddKeyedSingleton), which is added from .NET 7 on.
Define your own class that inherited RabbitConfiguration, for example:
public class FooConfiguration : RabbitConfiguration { }
public class BarConfiguration : RabbitConfiguration { }Add the configs of RabbitMQ connections in appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"FooConfiguration": {
"HostName": "localhost",
"Port": 5672,
"UserName": "admin",
"Password": "admin",
"VirtualHost": "/",
},
"BarConfiguration": {
"HostName": "localhost",
"Port": 5672,
"UserName": "admin",
"Password": "admin",
"VirtualHost": "/",
}
}Add RabbitHelper in Program.cs:
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddKeyedRabbitHelperFromAppSettings<FooConfiguration>("FooConnection", builder.Configuration);
builder.Services.AddKeyedRabbitHelperFromAppSettings<BarConfiguration>("BarConnection", builder.Configuration);To use your specified RabbitHelper, See here.
