-
Notifications
You must be signed in to change notification settings - Fork 3
DependencyInjection
- 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
RabbitConsumer
to 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";
});
})
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 DefaultMessageHandler
, which is a default implementation of IMessageHandler, you can simply inherit it and override the HandleMessage(string message)
to handle the messages in queue.
Sample code:
public class FooQueueHandler : DefaultMessageHandler
{
public override void HandleMessage(string message)
{
Console.WriteLine($"[x] Received from foo-queue: {message}");
Task.Delay(1000).Wait();
Console.WriteLine("[x] Done");
}
}
Then we could add a RabbitConsumer to RabbitHelper:
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";
});
})
.AddRabbitConsumer<FooQueueHandler>("FooConsumer", consumers: 1)
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)
{
_rabbitHelper.Publish("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";
});
}).AddKeyedRabbitConsumer<DefaultMessageHandler>("DefaultRabbitHelper", "DefaultFooConsumer");
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";
});
}).AddKeyedRabbitConsumer<DefaultMessageHandler>("TestRabbitHelper", "TestFooConsumer");
If you want to add RabbitConsumer to the Keyed RabbitHelper, you should use AddKeyedRabbitConsumer<THandler>(this IServiceCollection services, string key, string consumerName, int consumers = 1)
function, with the same key configured in AddKeyedRabbitHelper
.
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)
{
_rabbitHelper.Publish("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"
},
{
"ConsumerName": "BarConsumer",
"QueueName": "bar-queue"
}
]
}
}
Add RabbitHelper in Program.cs
:
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddRabbitHelperFromAppSettings<FooConfiguration>(builder.Configuration)
.AddRabbitConsumer<FooQueueHandler>("FooConsumer")
.AddRabbitConsumer<BarQueueHandler>("BarConsumer");
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.