Anixe.IO.Messaging.AspCore
2.1.0
See the version list below for details.
dotnet add package Anixe.IO.Messaging.AspCore --version 2.1.0
NuGet\Install-Package Anixe.IO.Messaging.AspCore -Version 2.1.0
<PackageReference Include="Anixe.IO.Messaging.AspCore" Version="2.1.0" />
paket add Anixe.IO.Messaging.AspCore --version 2.1.0
#r "nuget: Anixe.IO.Messaging.AspCore, 2.1.0"
// Install Anixe.IO.Messaging.AspCore as a Cake Addin #addin nuget:?package=Anixe.IO.Messaging.AspCore&version=2.1.0 // Install Anixe.IO.Messaging.AspCore as a Cake Tool #tool nuget:?package=Anixe.IO.Messaging.AspCore&version=2.1.0
Anixe.IO.Messaging.AspCore
Anixe.IO.Messaging.AspCore allows for quick integration of ASP.Core app with Anixe Messaging backed by RabbitMQ.
How to integrate
Add in csproj as a package reference
<PackageReference Include="Anixe.IO.Messaging.AspCore" Version="1.1.0" />
Register implementaion of IMessageFormatter
, default formatter can be found in Anixe.IO.Messaging.Serializer
<PackageReference Include="Anixe.IO.Messaging.Serializer" Version="1.0.0" />
Producer config
Add section to appsettings.json
{
...,
"Notifications": {
"ProducerConfiguration": {
"RabbitMqConfiguration": {
"Url": "amqp://guest:guest@localhost:5672/",
"AppName": "app_name"
},
"ExchangeConfiguration": {
"Name": "example.topic",
"Type": "topic",
"Durable" : true, // or false, the exchange will survive a broker restart
"ExchangeArguments": { } // custom arguments passed to the exchange declaration
},
"TenantFieldName": "tenant",
"Environment": "dev",
"AppName": "app_name",
"ContentEncoding": "gzip", // it will automatically gzip all messages.
"RetryPolicy": {
"Enabled": true,
"RetryCount": 3,
"SleepDurationMs": 200
}
}
}
}
Register services in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureProducerService(
this.config, cfg => {
// override NotificationsProducerConfiguration here
}
);
}
then in you business logic use INotificationService, provided by DI container
using Anixe.IO.Messaging.AspCore;
this.notificationService.SendNotification("routing.key", msg =>
{
msg.EntityId = "123";
msg.EntityType = "entityType";
msg.EntityUrl = "appName/entityType/123";
msg.Data = new { id = 123 };
// if operation is not provided, then based on REST convention by HTTP metod
msg.Operation = Anixe.IO.Messaging.Core.OperationType.Create;
});
In case of publish operation fail, exception is thrown.
Subscriber config
Add section to appsettings.json
{
...,
"Notifications": {
"SubscriberConfiguration": {
"RabbitMqConfiguration": {
"Url": "amqp://guest:guest@localhost:5672/",
"AppName": "app_name",
"Async": true // optional, to receive messages via AsyncEventingBasicConsumer
},
"QueueConfiguration": {
"QueueName": "", // unnamed queue
"Durable" : true, // or false, the queue will survive a broker restart
"Exclusive" : true, // or false, queue that has had at least one consumer is deleted when last consumer unsubscribes
"AutoDelete": true, // or false, Optional, used by plugins and broker-specific features such as message TTL, queue length limit, etc
"Bindings": [
{
"Exchange": "distro.topic",
"RoutingKeys": ["tenant.*.resource.sales_profile"],
"ExchangeArguments": { } // custom arguments passed to the exchange declaration
}
]
},
}
}
}
Also build-in rabbitmq channels can be setup
{
...,
"Notifications": {
"SubscriberConfiguration": {
"RabbitMqConfiguration": {
"Url": "amqp://guest:guest@localhost:5672/",
"AppName": "app_name",
"Async": true // optional, to receive messages via AsyncEventingBasicConsumer
},
"QueueConfiguration": {
"QueueName": "", // unnamed queue
"Bindings": [
{
"Exchange": "amq.fanout",
"ExchangeType": "fanout",
"RoutingKeys": []
}
]
}
}
}
}
Register services in Startup.cs.
Each ConfigureServices
registers the following dependencies:
ISubscriberConnection
singleton instanceListenerHostedService
hosted serviceISubscriberReloader
singleton instance
The following subscrubtion scenarios are possible:
Register single subscription for common NotificationMessage model
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureSubscriberService(this.config);
services.AddSingleton<IMessageReceiver<NotificationMessage>, MyNotificationHandler>(); // handle in my application
}
Optinally provide override configuration:
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureSubscriberService(this.config, opts => {
opts.RabbitMqConfiguration.Url = "amqp://example.com";
});
services.AddSingleton<IMessageReceiver<NotificationMessage>, MyNotificationHandler>(); // handle in my application
}
Register single subscription for generic NotificationMessage<Geolocation> model
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureSubscriberService<NotificationMessage<Geolocation>>(this.config);
services.AddSingleton<IMessageReceiver<NotificationMessage<Geolocation>>, MyNotificationHandler>(); // handle in my application
}
Register single subscription for many models, each per AMQP routing key
This scenario is usefull when many instances of the same subscriber must receive exact copy of published message (classic pub-sub)
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IMessageReceiver<NotificationMessage<Person>>, PersonModelHandler>();
services.AddSingleton<IMessageReceiver<NotificationMessage<List<Child>>>, ChildrenModelHandler>();
services.AddSingleton<IMessageReceiver<NotificationMessage<Child>>, ChildModelHandler>();
services.ConfigureSubscriberService(this.config, (builder) => {
builder
.AddMessageHandler<NotificationMessage<Person>>($"env.*.tenant.*.resource.person")
.AddMessageHandler<NotificationMessage<List<Child>>>($"env.*.tenant.*.resource.children")
.AddMessageHandler<NotificationMessage<Child>>($"env.*.tenant.*.resource.child");
});
}
or
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureSubscriberService(this.config, (builder) => {
builder
.AddMessageHandler<NotificationMessage<Person>, PersonModelHandler>($"env.*.tenant.*.resource.person")
.AddMessageHandler<NotificationMessage<List<Child>>, ChildrenModelHandler>($"env.*.tenant.*.resource.children")
.AddMessageHandler<NotificationMessage<Child>, ChildModelHandler>($"env.*.tenant.*.resource.child");
});
}
Register single subscription for many models with named queue, each per AMQP routing key
This scenario is usefull when many instances of the same subscriber must receive only one published message in round-robin manner.
Here all instances of this subscriber will share the same queue queue1
, so rabbitmq will distribute message in round-robin manner.
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureSubscriberService(this.config, (builder) => {
builder
.AddMessageHandler<NotificationMessage<Person>, PersonModelHandler>("queue1", $"env.*.tenant.*.resource.person")
.AddMessageHandler<NotificationMessage<List<Child>>, ChildrenModelHandler>("queue1", $"env.*.tenant.*.resource.children")
.AddMessageHandler<NotificationMessage<Child>, ChildModelHandler>("queue1", $"env.*.tenant.*.resource.child");
});
}
Register many subscriptions for many models, each per AMQP routing key
public void ConfigureServices(IServiceCollection services)
{
var geolinkSection = config.GetSection("GeolinkImporterNotifications");
services.ConfigureSubscriberService<GeoLocation>(rescSection);
services.AddSingleton<IMessageReceiver<GeoLocation>, GeoLocationNotificationHandler>();
var rescSection = config.GetSection("RESCNotifications");
services.ConfigureSubscriberService(this.config, (builder) => {
builder
.AddMessageHandler<NotificationMessage<Person>, PersonModelHandler>($"env.*.tenant.*.resource.person")
.AddMessageHandler<NotificationMessage<List<Child>>, ChildrenModelHandler>($"env.*.tenant.*.resource.children")
.AddMessageHandler<NotificationMessage<Child>, ChildModelHandler>($"env.*.tenant.*.resource.child");
});
}
Routing keys from AddMessageHandler
will replace these from appsettings.json
Register custom connection
public void ConfigureServices(IServiceCollection services)
{
var conn = new MyCustomSubscriberConnection();
services.ConfigureSubscriberService(this.config, (builder) => {
builder
.AddCustomConnection(conn)
/*chain other registrations*/
;
});
}
Register NewtonsoftJson deserializer
Add Anixe.IO.Messaging.Serializer
assembly to csproj then:
public void ConfigureServices(IServiceCollection services)
{
var conn = new MyCustomSubscriberConnection();
services.ConfigureSubscriberService(this.config, (builder) => {
builder
.AddCustomFormatter<NewtonsoftMessageFormatter>()
/*chain other registrations*/
;
});
}
Deserializing notification messages
By default Anixe.IO.Messaging provides NotificationMessage
and NotificationMessage<T>
build-in classes which implelement Resfinity Entity Consistent System convention. These classes are envelopes for Data
property which can provide custom data:
- In
NotificationMessage
theData
isobject
and deserializes into .Net primitives like Dictionary<string, object>, List<T>, string and value typed - In
NotificationMessage<T>
theData
is instance ofT
and and deserializes into generic model
But you don't have to use NotificationMessage
class, you can provide your own type.
Check src/Anixe.IO.Messaging.Test/Core/MessageFormatterTest.cs
for serialization/deserialization examples
Example for NotificationMessage
registration (implicit)
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureSubscriberService(this.config); // receive and deserialize
services.AddSingleton<IMessageReceiver<NotificationMessage>, MyNotificationHandler>(); // handle in my application
}
Example for NotificationMessage<T>
registration
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureSubscriberService<NotificationMessage<Person>>(this.config); // receive and deserialize
services.AddSingleton<IMessageReceiver<NotificationMessage<Person>>, MyNotificationHandler>(); // handle in my application
}
Example for any model registration
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureSubscriberService<GeoLocation>(this.config); // receive and deserialize
services.AddSingleton<IMessageReceiver<GeoLocation>, GeoLocationNotificationHandler>(); // handle in my application
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
.NET Core | netcoreapp3.0 is compatible. netcoreapp3.1 is compatible. |
-
.NETCoreApp 3.0
- Anixe.IO.Messaging (>= 2.1.0)
-
.NETCoreApp 3.1
- Anixe.IO.Messaging (>= 2.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
4.0.0 | 6,182 | 1/8/2024 |
3.0.1 | 742 | 12/4/2023 |
3.0.0 | 4,752 | 11/22/2022 |
2.2.1 | 734 | 11/21/2022 |
2.2.0 | 416 | 10/18/2022 |
2.1.1 | 1,096 | 10/18/2022 |
2.1.0 | 10,163 | 8/31/2021 |
2.0.1 | 1,584 | 7/8/2021 |
2.0.0 | 1,613 | 4/16/2021 |
1.1.14 | 1,014 | 1/27/2021 |
1.1.13 | 550 | 11/23/2020 |
1.1.12 | 413 | 11/16/2020 |
1.1.11 | 1,362 | 10/22/2020 |
1.1.9 | 592 | 9/29/2020 |
1.1.8 | 2,329 | 5/21/2020 |
1.1.7 | 666 | 5/19/2020 |
1.1.6 | 507 | 5/19/2020 |
1.1.5 | 593 | 5/8/2020 |
1.1.4 | 805 | 4/20/2020 |
1.1.3 | 536 | 4/17/2020 |
1.1.2 | 486 | 4/15/2020 |
1.1.1 | 643 | 4/2/2020 |
1.1.0 | 587 | 3/26/2020 |
1.0.4 | 514 | 3/20/2020 |
1.0.3 | 542 | 3/19/2020 |
1.0.2 | 611 | 3/13/2020 |
1.0.1 | 577 | 3/4/2020 |
0.1.0 | 580 | 2/27/2020 |