The Owlery library provides the ability to consume and publish to RabbitMQ queues with ease.
The Owlery library provides .NET Core developers the ability to consume and publish to RabbitMQ queues with the same ease as creating a new ApiController.
The following are a few examples of how Owlery can help you.
The following is added in the ConfigureServices
method in the Startup.cs
file.
using Owlery.Extensions;
...
public void ConfigureServices(IServiceCollection services)
{
services.AddRabbitControllers();
...
}
Then we create two consumers in a controller class. The textConsumer
method
consumes messages from the tester.test
queue and creates a new instance of the
AModel
class. This is then published to the tester.another.test
queue via
the testExc
exchange. The anotherTestConsumer
method consumes messages for
tester.another.test
and logs the AModel
instances it recieves.
using Microsoft.Extensions.Logging;
using Owlery;
[RabbitController]
public class OwleryController
{
private readonly ILogger logger;
public OwleryController(ILogger<OwleryController> logger)
{
this.logger = logger;
}
[RabbitConsumer(queueName: "tester.test")]
[RabbitPublisher(routingKey: "tester.another.test")]
public AModel testConsumer()
{
logger.LogInformation($"Creating model");
return new AModel {
AnInteger = 99,
AString = "This is a string",
};
}
[RabbitConsumer(queueName: "tester.another.test")]
public void anotherTestConsumer([FromBody] AModel aModel)
{
logger.LogInformation($"Received a model {aModel}");
}
}
public class AModel
{
public int AnInteger { get; set; }
public string AString { get; set; }
public override string ToString()
{
return $"[AModel AnInteger: {this.AnInteger}, AString: {this.AString}]";
}
}
To publish a message to an exchange Dependency Injection is used. First we require the IRabbitService in the constructor.
using Owlery.Services;
...
private readonly IRabbitService rabbitService;
public ClassConstructor(
IRabbitService rabbitService)
{
this.rabbitService = rabbitService;
}
Then we can use the Publish
method to publish the message
this.rabbitService.Publish(body: "Message body", routingKey: "tester.test", exchange: "");
But we can use any JSONSerializable object as the body, or an array of bytes directly.
If we need to apply any custom properties to the message being published we can
pass a RabbitMessage
to the Publish
method. The following is an example of
how to apply custom headers to a message:
RabbitMessage message = new RabbitMessage {
Body = "Message body",
Headers = new Dictionary<string, object> {
{"x-origin", "Origin of message"},
},
};
this.rabbitService.Publish(message, "tester.test");
Automatically declare queues, exchanges and bind queues to exchanges when the application starts using configuration only.
In appsettings.json
or any other configuration source define the following
{
...
"Owlery": {
"Queues": {
"TestQueue": {
"QueueName": "tester.test"
},
"AnotherQueue": {
"QueueName": "tester.another.test"
}
},
"Exchanges": {
"AnExchange": {
"ExchangeName": "testExc"
}
},
"Bindings": {
"ABinding": {
"QueueName": "tester.another.test",
"ExchangeName": "testExc",
"RoutingKey": "tester.routingKey"
}
}
}
}
The following is added in the ConfigureServices
method in the Startup.cs
file.
using Owlery.Extensions;
...
public void ConfigureServices(IServiceCollection services)
{
services.AddRabbitControllers(Configuration.GetSection("Owlery"));
...
}
We can use queue and exchange names as well as routing keys defined in configuration. If we assume the config is defined as it is in the Declaring queues section then the following works.
[RabbitConsumer(queueName: "{Owlery:Queues:TestQueue:QueueName}")]
[RabbitPublisher(routingKey: "{Owlery:Bindings:ABinding:RoutingKey}", exchangeName: "{Owlery:Bindings:ABinding:ExchangeName}")]
We can of course reference any settings key. For example with the following configuration and consumer definition.
{
"MyQueueSettings": {
"Queue": "name.of.queue"
}
}
[RabbitConsumer(queueName: "{MyQueueSettings:Queue}")]