From be4f2e1e176c57b51fba8ae1728c40dc278e4a78 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sat, 7 Jun 2025 22:41:31 +0200 Subject: [PATCH 01/16] :sparkles: support for RabbitMQ --- .../Commands/RabbitMqCommandQueue.cs | 121 ++++++++++++++++++ .../Commands/RabbitMqCommandQueueOptions.cs | 65 ++++++++++ .../EventDriven/RabbitMqEventBus.cs | 108 ++++++++++++++++ .../EventDriven/RabbitMqEventBusOptions.cs | 51 ++++++++ .../RabbitMqMessage.cs | 112 ++++++++++++++++ .../RabbitMqMessageOptions.cs | 54 ++++++++ .../Savvyio.Extensions.RabbitMQ.csproj | 21 +++ 7 files changed, 532 insertions(+) create mode 100644 src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs create mode 100644 src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs create mode 100644 src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBus.cs create mode 100644 src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBusOptions.cs create mode 100644 src/Savvyio.Extensions.RabbitMQ/RabbitMqMessage.cs create mode 100644 src/Savvyio.Extensions.RabbitMQ/RabbitMqMessageOptions.cs create mode 100644 src/Savvyio.Extensions.RabbitMQ/Savvyio.Extensions.RabbitMQ.csproj diff --git a/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs new file mode 100644 index 0000000..daf5db5 --- /dev/null +++ b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs @@ -0,0 +1,121 @@ +using Cuemon; +using Cuemon.Extensions; +using Cuemon.Extensions.IO; +using Cuemon.Extensions.Reflection; +using Cuemon.Threading; +using RabbitMQ.Client; +using RabbitMQ.Client.Events; +using Savvyio.Commands; +using Savvyio.Messaging; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Channels; +using System.Threading.Tasks; + +namespace Savvyio.Extensions.RabbitMQ.Commands +{ + /// + /// Represents a RabbitMQ-based implementation of a point-to-point command queue. + /// + public class RabbitMqCommandQueue : RabbitMqMessage, IPointToPointChannel + { + private readonly RabbitMqCommandQueueOptions _options; + + /// + /// Initializes a new instance of the class. + /// + /// The marshaller used for serializing and deserializing messages. + /// The options used to configure the RabbitMQ command queue. + /// + /// cannot be null -or- + /// cannot be null. + /// + /// + /// are not in a valid state. + /// + public RabbitMqCommandQueue(IMarshaller marshaller, RabbitMqCommandQueueOptions options) : base(marshaller, options) + { + Validator.ThrowIfInvalidOptions(options); + _options = options; + } + + /// + /// Sends the specified command messages asynchronously to the configured RabbitMQ queue. + /// + /// The messages to send. + /// The which may be configured. + /// A that represents the asynchronous operation. + public async Task SendAsync(IEnumerable> messages, Action setup = null) + { + Validator.ThrowIfInvalidConfigurator(setup, out var options); + + await EnsureConnectivityAsync(options.CancellationToken).ConfigureAwait(false); + + await RabbitMqChannel.QueueDeclareAsync(_options.QueueName, false, false, false, cancellationToken: options.CancellationToken).ConfigureAwait(false); + + foreach (var message in messages) + { + await RabbitMqChannel.BasicPublishAsync("", _options.QueueName, true, basicProperties: new BasicProperties() + { + //Persistent = true, + Headers = new Dictionary() + { + { MessageType, message.GetType().ToFullNameIncludingAssemblyName() } + } + }, body: await Marshaller.Serialize(message).ToByteArrayAsync(o => o.CancellationToken = options.CancellationToken).ConfigureAwait(false), options.CancellationToken).ConfigureAwait(false); + } + } + + /// + /// Receives command messages asynchronously from the configured RabbitMQ queue. + /// + /// The which may be configured. + /// + /// An that yields instances as they are received. + /// + public async IAsyncEnumerable> ReceiveAsync(Action setup = null) + { + Validator.ThrowIfInvalidConfigurator(setup, out var options); + + await EnsureConnectivityAsync(options.CancellationToken).ConfigureAwait(false); + + await RabbitMqChannel.QueueDeclareAsync(_options.QueueName, false, false, false, cancellationToken: options.CancellationToken).ConfigureAwait(false); + + var buffer = Channel.CreateUnbounded>(); + var consumer = new AsyncEventingBasicConsumer(RabbitMqChannel); + consumer.ReceivedAsync += async (_, e) => + { + var messageType = Type.GetType((e.BasicProperties.Headers[MessageType] as byte[]).ToEncodedString()); + var deserialized = Marshaller.Deserialize(e.Body.ToArray().ToStream(), messageType) as IMessage; + deserialized!.Properties.Add(nameof(BasicDeliverEventArgs.DeliveryTag), e.DeliveryTag); + deserialized.Properties.Add(nameof(CancellationToken), options.CancellationToken); + deserialized.Properties.Add(nameof(QueueDeclareOk.QueueName), _options.QueueName); + await buffer.Writer.WriteAsync(deserialized, options.CancellationToken).ConfigureAwait(false); + }; + + await RabbitMqChannel.BasicConsumeAsync(_options.QueueName, autoAck: false, consumer: consumer, cancellationToken: options.CancellationToken).ConfigureAwait(false); + + while (await buffer.Reader.WaitToReadAsync(options.CancellationToken).ConfigureAwait(false)) + { + while (buffer.Reader.TryRead(out var message)) + { + message.Acknowledged += OnMessageAcknowledgedAsync; + if (_options.AutoAcknowledge) + { + await message.AcknowledgeAsync().ConfigureAwait(false); + } + yield return message; + } + } + } + + private async Task OnMessageAcknowledgedAsync(object sender, AcknowledgedEventArgs e) + { + var ct = (CancellationToken)e.Properties[nameof(CancellationToken)]; + var queueName = e.Properties[nameof(QueueDeclareOk.QueueName)] as string; + await RabbitMqChannel.QueueDeclareAsync(queueName, false, false, false, cancellationToken: ct).ConfigureAwait(false); + await RabbitMqChannel.BasicAckAsync((ulong)e.Properties[nameof(BasicDeliverEventArgs.DeliveryTag)], false, ct).ConfigureAwait(false); + } + } +} diff --git a/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs new file mode 100644 index 0000000..2edceed --- /dev/null +++ b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs @@ -0,0 +1,65 @@ +using System; +using Cuemon; + +namespace Savvyio.Extensions.RabbitMQ.Commands +{ + /// + /// Configuration options for . + /// + /// + public class RabbitMqCommandQueueOptions : RabbitMqMessageOptions + { + /// + /// Initializes a new instance of the class with default values. + /// + /// + /// The following table shows the initial property values for an instance of . + /// + /// + /// Property + /// Initial Value + /// + /// + /// + /// null + /// + /// + /// + /// false + /// + /// + /// + public RabbitMqCommandQueueOptions() + { + } + + /// + /// Gets or sets the name of the queue. + /// + /// + /// The name of the RabbitMQ queue to be used for command messages. + /// + public string QueueName { get; set; } + + /// + /// Gets or sets a value indicating whether messages should be automatically acknowledged. + /// + /// + /// true if messages are automatically acknowledged; otherwise, false. + /// + public bool AutoAcknowledge { get; set; } + + /// + /// Determines whether the public read-write properties of this instance are in a valid state. + /// + /// This method is expected to throw exceptions when one or more conditions fails to be in a valid state. + /// + /// cannot be null or empty. + /// + public override void ValidateOptions() + { + Validator.ThrowIfInvalidState(string.IsNullOrEmpty(QueueName)); + base.ValidateOptions(); + } + } +} diff --git a/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBus.cs b/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBus.cs new file mode 100644 index 0000000..4eb22b5 --- /dev/null +++ b/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBus.cs @@ -0,0 +1,108 @@ +using Cuemon; +using Cuemon.Extensions; +using Cuemon.Extensions.IO; +using Cuemon.Extensions.Reflection; +using Cuemon.Threading; +using RabbitMQ.Client; +using RabbitMQ.Client.Events; +using Savvyio.EventDriven; +using Savvyio.Messaging; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Channels; +using System.Threading.Tasks; + +namespace Savvyio.Extensions.RabbitMQ.EventDriven +{ + /// + /// Represents a RabbitMQ-based implementation of a publish-subscribe event bus for integration events. + /// + public class RabbitMqEventBus : RabbitMqMessage, IPublishSubscribeChannel + { + private readonly ConnectionFactory _factory; + private readonly RabbitMqEventBusOptions _options; + + /// + /// Initializes a new instance of the class. + /// + /// The marshaller used for serializing and deserializing messages. + /// The options used to configure the RabbitMQ event bus. + /// + /// cannot be null -or- + /// cannot be null. + /// + /// + /// are not in a valid state. + /// + public RabbitMqEventBus(IMarshaller marshaller, RabbitMqEventBusOptions options) : base(marshaller, options) + { + Validator.ThrowIfInvalidOptions(options); + _options = options; + } + + /// + /// Publishes the specified integration event message asynchronously to the configured RabbitMQ exchange. + /// + /// The message to publish. + /// The which may be configured. + /// A that represents the asynchronous operation. + public async Task PublishAsync(IMessage message, Action setup = null) + { + Validator.ThrowIfInvalidConfigurator(setup, out var options); + + await EnsureConnectivityAsync(options.CancellationToken).ConfigureAwait(false); + + await RabbitMqChannel.ExchangeDeclareAsync(_options.ExchangeName, ExchangeType.Fanout, cancellationToken: options.CancellationToken).ConfigureAwait(false); + + await RabbitMqChannel.BasicPublishAsync(_options.ExchangeName, "", false, basicProperties: new BasicProperties() + { + Headers = new Dictionary() + { + { MessageType, message.GetType().ToFullNameIncludingAssemblyName() } + } + }, body: await Marshaller.Serialize(message).ToByteArrayAsync(o => o.CancellationToken = options.CancellationToken).ConfigureAwait(false), options.CancellationToken).ConfigureAwait(false); + } + + /// + /// Subscribes to integration event messages from the configured RabbitMQ exchange and invokes the specified asynchronous handler for each received message. + /// + /// The function delegate that will handle the message. + /// The which may be configured. + /// A that represents the asynchronous operation. + public async Task SubscribeAsync(Func, CancellationToken, Task> asyncHandler, Action setup = null) + { + Validator.ThrowIfInvalidConfigurator(setup, out var options); + + await EnsureConnectivityAsync(options.CancellationToken).ConfigureAwait(false); + + await RabbitMqChannel.ExchangeDeclareAsync(_options.ExchangeName, ExchangeType.Fanout, cancellationToken: options.CancellationToken).ConfigureAwait(false); + + var queue = await RabbitMqChannel.QueueDeclareAsync(cancellationToken: options.CancellationToken).ConfigureAwait(false); + + await RabbitMqChannel.QueueBindAsync(queue.QueueName, _options.ExchangeName, "", cancellationToken: options.CancellationToken).ConfigureAwait(false); + + var buffer = Channel.CreateUnbounded>(); + var consumer = new AsyncEventingBasicConsumer(RabbitMqChannel); + consumer.ReceivedAsync += async (_, e) => + { + var messageType = Type.GetType((e.BasicProperties.Headers[MessageType] as byte[]).ToEncodedString()); + var deserialized = Marshaller.Deserialize(e.Body.ToArray().ToStream(), messageType) as IMessage; + deserialized!.Properties.Add(nameof(BasicDeliverEventArgs.DeliveryTag), e.DeliveryTag); + deserialized.Properties.Add(nameof(CancellationToken), options.CancellationToken); + deserialized.Properties.Add(nameof(QueueDeclareOk.QueueName), queue.QueueName); + await buffer.Writer.WriteAsync(deserialized, options.CancellationToken).ConfigureAwait(false); + }; + + await RabbitMqChannel.BasicConsumeAsync(queue.QueueName, autoAck: true, consumer: consumer, options.CancellationToken).ConfigureAwait(false); + + while (await buffer.Reader.WaitToReadAsync(options.CancellationToken).ConfigureAwait(false)) + { + while (buffer.Reader.TryRead(out var message)) + { + await asyncHandler(message, options.CancellationToken).ConfigureAwait(false); + } + } + } + } +} diff --git a/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBusOptions.cs b/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBusOptions.cs new file mode 100644 index 0000000..bc0bef1 --- /dev/null +++ b/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBusOptions.cs @@ -0,0 +1,51 @@ +using System; +using Cuemon; + +namespace Savvyio.Extensions.RabbitMQ.EventDriven +{ + /// + /// Configuration options for . + /// + /// + public class RabbitMqEventBusOptions : RabbitMqMessageOptions + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The following table shows the initial property values for an instance of . + /// + /// + /// Property + /// Initial Value + /// + /// + /// + /// null + /// + /// + /// + public RabbitMqEventBusOptions() + { + } + + /// + /// Gets or sets the name of the exchange. + /// + /// The name of the exchange. + public string ExchangeName { get; set; } + + /// + /// Determines whether the public read-write properties of this instance are in a valid state. + /// + /// This method is expected to throw exceptions when one or more conditions fails to be in a valid state. + /// + /// cannot be null or empty. + /// + public override void ValidateOptions() + { + Validator.ThrowIfInvalidState(string.IsNullOrEmpty(ExchangeName)); + base.ValidateOptions(); + } + } +} diff --git a/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessage.cs b/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessage.cs new file mode 100644 index 0000000..ace4d2e --- /dev/null +++ b/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessage.cs @@ -0,0 +1,112 @@ +using System; +using Cuemon; +using Cuemon.Extensions; +using RabbitMQ.Client; +using System.Threading; +using System.Threading.Tasks; + +namespace Savvyio.Extensions.RabbitMQ +{ + /// + /// Provides a base class for RabbitMQ message operations, including connection and channel management, marshalling, and resource disposal. Ensures thread-safe initialization of RabbitMQ connectivity. + /// + public abstract class RabbitMqMessage : AsyncDisposable + { + /// + /// The header key used to indicate the message type in RabbitMQ properties. + /// + protected const string MessageType = "type"; + + private readonly SemaphoreSlim _asyncLock = new(1, 1); + private bool _initialized; + + /// + /// Initializes a new instance of the class with the specified marshaller and options. + /// + /// The marshaller used for serializing and deserializing messages. + /// The options used to configure the RabbitMQ connection. + /// + /// cannot be null -or- + /// cannot be null. + /// + /// + /// are not in a valid state. + /// + protected RabbitMqMessage(IMarshaller marshaller, RabbitMqMessageOptions options) + { + Validator.ThrowIfInvalidOptions(options); + Validator.ThrowIfNull(marshaller); + Marshaller = marshaller; + RabbitMqFactory = new ConnectionFactory + { + Uri = options.AmqpUrl + }; + } + + /// + /// Gets the RabbitMQ connection factory used to create connections to the broker. + /// + protected ConnectionFactory RabbitMqFactory { get; } + + /// + /// Ensures that a connection and channel to the RabbitMQ broker are established and initialized. + /// This method is thread-safe and will only initialize the connection and channel once. + /// + /// + /// A that can be used to cancel the asynchronous operation. + /// + /// + /// A representing the asynchronous operation. + /// + /// + /// If the connection and channel are already initialized, this method returns immediately. + /// Otherwise, it acquires an asynchronous lock to ensure only one initialization occurs, + /// then creates the RabbitMQ connection and channel. + /// + protected async Task EnsureConnectivityAsync(CancellationToken ct) + { + if (_initialized) { return; } + await _asyncLock.WaitAsync(ct).ConfigureAwait(false); + try + { + if (!_initialized) + { + RabbitMqConnection = await RabbitMqFactory.CreateConnectionAsync(ct).ConfigureAwait(false); + RabbitMqChannel = await RabbitMqConnection.CreateChannelAsync(cancellationToken: ct).ConfigureAwait(false); + _initialized = true; + } + } + finally + { + _asyncLock.Release(); + } + } + + /// + /// Gets the current RabbitMQ connection instance. + /// + protected IConnection RabbitMqConnection { get; private set; } + + /// + /// Gets the current RabbitMQ channel instance. + /// + protected IChannel RabbitMqChannel { get; private set; } + + /// + /// Gets the by constructor provided serializer context. + /// + /// The by constructor provided serializer context. + protected IMarshaller Marshaller { get; } + + /// + /// Called when this object is being disposed by . + /// Disposes the RabbitMQ channel and connection asynchronously if they have been initialized. + /// + /// A representing the asynchronous dispose operation. + protected override async ValueTask OnDisposeManagedResourcesAsync() + { + if (RabbitMqChannel != null) { await RabbitMqChannel.DisposeAsync(); } + if (RabbitMqConnection != null) { await RabbitMqConnection.DisposeAsync(); } + } + } +} diff --git a/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessageOptions.cs b/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessageOptions.cs new file mode 100644 index 0000000..19ff9f6 --- /dev/null +++ b/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessageOptions.cs @@ -0,0 +1,54 @@ +using System; +using Cuemon; +using Cuemon.Configuration; + +namespace Savvyio.Extensions.RabbitMQ +{ + /// + /// Configuration options that is related to RabbitMQ. + /// + /// + public class RabbitMqMessageOptions : IValidatableParameterObject + { + /// + /// Initializes a new instance of the class with default values. + /// + /// + /// The following table shows the initial property values for an instance of . + /// + /// + /// Property + /// Initial Value + /// + /// + /// + /// new Uri("amqp://localhost:5672") + /// + /// + /// + public RabbitMqMessageOptions() + { + AmqpUrl = new Uri("amqp://localhost:5672"); + } + + /// + /// Gets or sets the AMQP URL used to connect to the RabbitMQ broker. + /// + /// + /// The representing the AMQP endpoint for the RabbitMQ broker. + /// + public Uri AmqpUrl { get; set; } + + /// + /// Determines whether the public read-write properties of this instance are in a valid state. + /// + /// This method is expected to throw exceptions when one or more conditions fails to be in a valid state. + /// + /// cannot be null. + /// + public virtual void ValidateOptions() + { + Validator.ThrowIfInvalidState(AmqpUrl == null); + } + } +} diff --git a/src/Savvyio.Extensions.RabbitMQ/Savvyio.Extensions.RabbitMQ.csproj b/src/Savvyio.Extensions.RabbitMQ/Savvyio.Extensions.RabbitMQ.csproj new file mode 100644 index 0000000..62f517e --- /dev/null +++ b/src/Savvyio.Extensions.RabbitMQ/Savvyio.Extensions.RabbitMQ.csproj @@ -0,0 +1,21 @@ + + + + Extend the Savvy I/O core assemblies with support for RabbitMQ Work Queue and RabbitMQ Publish-Subscribe. + azure queue storage event-grid bus + + + + + + + + + + + + + + + + From f339eb87787f3eaa8192aea97ed6c7173b2b45eb Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sat, 7 Jun 2025 22:41:58 +0200 Subject: [PATCH 02/16] :white_check_mark: functional test for RabbitMQ --- .../Assets/CreateMemberCommand.cs | 20 ++ .../Assets/MemberCreated.cs | 17 + ...MqCommandQueueJsonSerializerContextTest.cs | 187 +++++++++++ ...ueueNewtonsoftJsonSerializerContextTest.cs | 167 ++++++++++ ...bbitMqEventBusJsonSerializerContextTest.cs | 298 ++++++++++++++++++ ...tBusNewtonsoftJsonSerializerContextTest.cs | 298 ++++++++++++++++++ ...Extensions.RabbitMQ.FunctionalTests.csproj | 21 ++ 7 files changed, 1008 insertions(+) create mode 100644 test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Assets/CreateMemberCommand.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Assets/MemberCreated.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Commands/RabbitMqCommandQueueJsonSerializerContextTest.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Commands/RabbitMqCommandQueueNewtonsoftJsonSerializerContextTest.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.FunctionalTests/EventDriven/RabbitMqEventBusJsonSerializerContextTest.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.FunctionalTests/EventDriven/RabbitMqEventBusNewtonsoftJsonSerializerContextTest.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Savvyio.Extensions.RabbitMQ.FunctionalTests.csproj diff --git a/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Assets/CreateMemberCommand.cs b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Assets/CreateMemberCommand.cs new file mode 100644 index 0000000..18851b1 --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Assets/CreateMemberCommand.cs @@ -0,0 +1,20 @@ +using Savvyio.Commands; + +namespace Savvyio.Extensions.RabbitMQ.Assets +{ + internal record CreateMemberCommand : Command + { + public CreateMemberCommand(string name, byte age, string emailAddress) + { + Name = name; + Age = age; + EmailAddress = emailAddress; + } + + public string Name { get; } + + public byte Age { get; } + + public string EmailAddress { get; } + } +} diff --git a/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Assets/MemberCreated.cs b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Assets/MemberCreated.cs new file mode 100644 index 0000000..0958beb --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Assets/MemberCreated.cs @@ -0,0 +1,17 @@ +using Savvyio.EventDriven; + +namespace Savvyio.Extensions.RabbitMQ.Assets +{ + public record MemberCreated : IntegrationEvent + { + public MemberCreated(string name, string emailAddress) + { + Name = name; + EmailAddress = emailAddress; + } + + public string Name { get; } + + public string EmailAddress { get; } + } +} diff --git a/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Commands/RabbitMqCommandQueueJsonSerializerContextTest.cs b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Commands/RabbitMqCommandQueueJsonSerializerContextTest.cs new file mode 100644 index 0000000..854c6b1 --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Commands/RabbitMqCommandQueueJsonSerializerContextTest.cs @@ -0,0 +1,187 @@ +using System.Linq; +using System.Threading.Channels; +using System.Threading.Tasks; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting; +using Cuemon; +using Cuemon.Extensions; +using Cuemon.Extensions.Collections.Generic; +using Cuemon.Extensions.IO; +using Microsoft.Extensions.DependencyInjection; +using Savvyio.Commands; +using Savvyio.Commands.Messaging; +using Savvyio.Extensions.DependencyInjection; +using Savvyio.Extensions.DependencyInjection.Messaging; +using Savvyio.Extensions.RabbitMQ.Assets; +using Savvyio.Extensions.Text.Json; +using Savvyio.Messaging; +using Savvyio.Messaging.Cryptography; +using Xunit; +using Xunit.Abstractions; + +namespace Savvyio.Extensions.RabbitMQ.Commands +{ + public class RabbitMqCommandQueueJsonSerializerContextTest : Test + { + public RabbitMqCommandQueueJsonSerializerContextTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public async Task ReceiveAndSendAsync_CreateMemberCommand_OneTime() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageQueue().AddConfiguredOptions(o => + { + o.AutoAcknowledge = true; + o.QueueName = "queue1"; + }); + }); + + var queue = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new CreateMemberCommand("John Doe", 44, "jd@outlook.com"); + var urn = "https://fancy.io/members".ToUri(); + var message = member.ToMessage(urn, nameof(CreateMemberCommand)); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + + Task.Run(async () => + { + await foreach (var msg in queue.ReceiveAsync().ConfigureAwait(false)) + { + await receivedMessages.Writer.WriteAsync(msg).ConfigureAwait(false); + } + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await queue.SendAsync(message.Yield()).ConfigureAwait(false); + + await Task.Delay(500); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync(); + + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + } + + [Fact] + public async Task ReceiveAndSendAsync_CreateMemberCommand_OneTime_Signed() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageQueue().AddConfiguredOptions(o => o.QueueName = Generate.RandomString(10)); + }); + + var queue = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new CreateMemberCommand("John Doe", 44, "jd@outlook.com"); + var urn = "https://fancy.io/members/signed".ToUri(); + var message = member.ToMessage(urn, nameof(CreateMemberCommand)).Sign(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + + Task.Run(async () => + { + await foreach (var msg in queue.ReceiveAsync().ConfigureAwait(false)) + { + await receivedMessages.Writer.WriteAsync(msg).ConfigureAwait(false); + } + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await queue.SendAsync(message.Yield()).ConfigureAwait(false); + + await Task.Delay(500); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = (await receivedMessages.Reader.ReadAsync()) as ISignedMessage; + received?.CheckSignature(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + } + + [Fact] + public async Task ReceiveAndSendAsync_CreateMemberCommand_HundredTimes() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageQueue().AddConfiguredOptions(o => o.QueueName = Generate.RandomString(10)); + }); + + var queue = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var messages = Generate.RangeOf(100, i => + { + var email = $"{Generate.RandomString(5)}@outlook.com"; + var message = new CreateMemberCommand(Generate.RandomString(10), (byte)Generate.RandomNumber(byte.MaxValue), email).ToMessage($"urn:{i}:{email}".ToUri(), nameof(CreateMemberCommand)); + return message; + }).ToList(); + + var receivedMessages = Channel.CreateUnbounded>(); + + var count1 = 0; + Task.Run(async () => + { + await foreach (var msg in queue.ReceiveAsync().ConfigureAwait(false)) + { + count1++; + await receivedMessages.Writer.WriteAsync(msg).ConfigureAwait(false); + } + }); + + var count2 = 0; + Task.Run(async () => + { + await foreach (var msg in queue.ReceiveAsync().ConfigureAwait(false)) + { + count2++; + await receivedMessages.Writer.WriteAsync(msg).ConfigureAwait(false); + } + }); + + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await queue.SendAsync(messages).ConfigureAwait(false); + + await Task.Delay(750); + + TestOutput.WriteLine(count1.ToString()); + TestOutput.WriteLine(count2.ToString()); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAllAsync().ToListAsync(); + + TestOutput.WriteLine(received.Count.ToString()); + TestOutput.WriteLines(received.Take(10)); + + Assert.Equivalent(messages.Count, received.Count); + Assert.Equivalent(messages, received); + Assert.Equivalent(messages.Select(message => message.Data), received.Select(message => message.Data)); + Assert.Equivalent(messages.Select(message => message.Data.Metadata), received.Select(message => message.Data.Metadata)); + } + } +} diff --git a/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Commands/RabbitMqCommandQueueNewtonsoftJsonSerializerContextTest.cs b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Commands/RabbitMqCommandQueueNewtonsoftJsonSerializerContextTest.cs new file mode 100644 index 0000000..b41d789 --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Commands/RabbitMqCommandQueueNewtonsoftJsonSerializerContextTest.cs @@ -0,0 +1,167 @@ +using System.Linq; +using System.Threading.Channels; +using System.Threading.Tasks; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting; +using Cuemon; +using Cuemon.Extensions; +using Cuemon.Extensions.Collections.Generic; +using Cuemon.Extensions.IO; +using Microsoft.Extensions.DependencyInjection; +using Savvyio.Commands; +using Savvyio.Commands.Messaging; +using Savvyio.Extensions.DependencyInjection; +using Savvyio.Extensions.DependencyInjection.Messaging; +using Savvyio.Extensions.Newtonsoft.Json; +using Savvyio.Extensions.RabbitMQ.Assets; +using Savvyio.Messaging; +using Savvyio.Messaging.Cryptography; +using Xunit; +using Xunit.Abstractions; + +namespace Savvyio.Extensions.RabbitMQ.Commands +{ + public class RabbitMqCommandQueueNewtonsoftJsonSerializerContextTest : Test + { + public RabbitMqCommandQueueNewtonsoftJsonSerializerContextTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public async Task ReceiveAndSendAsync_CreateMemberCommand_OneTime() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageQueue().AddConfiguredOptions(o => o.QueueName = Generate.RandomString(10)); + }); + + var queue = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new CreateMemberCommand("John Doe", 44, "jd@outlook.com"); + var urn = "https://fancy.io/members".ToUri(); + var message = member.ToMessage(urn, nameof(CreateMemberCommand)); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + + Task.Run(async () => + { + await foreach (var msg in queue.ReceiveAsync().ConfigureAwait(false)) + { + await receivedMessages.Writer.WriteAsync(msg).ConfigureAwait(false); + } + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await queue.SendAsync(message.Yield()).ConfigureAwait(false); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync(); + + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + } + + [Fact] + public async Task ReceiveAndSendAsync_CreateMemberCommand_OneTime_Signed() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageQueue().AddConfiguredOptions(o => o.QueueName = Generate.RandomString(10)); + }); + + var queue = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new CreateMemberCommand("John Doe", 44, "jd@outlook.com"); + var urn = "https://fancy.io/members/signed".ToUri(); + var message = member.ToMessage(urn, nameof(CreateMemberCommand)).Sign(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + + Task.Run(async () => + { + await foreach (var msg in queue.ReceiveAsync().ConfigureAwait(false)) + { + await receivedMessages.Writer.WriteAsync(msg).ConfigureAwait(false); + } + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await queue.SendAsync(message.Yield()).ConfigureAwait(false); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = (await receivedMessages.Reader.ReadAsync()) as ISignedMessage; + received?.CheckSignature(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + } + + [Fact] + public async Task ReceiveAndSendAsync_CreateMemberCommand_HundredTimes() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageQueue().AddConfiguredOptions(o => o.QueueName = Generate.RandomString(10)); + }); + + var queue = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var messages = Generate.RangeOf(100, i => + { + var email = $"{Generate.RandomString(5)}@outlook.com"; + var message = new CreateMemberCommand(Generate.RandomString(10), (byte)Generate.RandomNumber(byte.MaxValue), email).ToMessage($"urn:{i}:{email}".ToUri(), nameof(CreateMemberCommand)); + return message; + }).ToList(); + + var receivedMessages = Channel.CreateUnbounded>(); + + Task.Run(async () => + { + await foreach (var msg in queue.ReceiveAsync().ConfigureAwait(false)) + { + await receivedMessages.Writer.WriteAsync(msg).ConfigureAwait(false); + } + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await queue.SendAsync(messages).ConfigureAwait(false); + + await Task.Delay(750); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAllAsync().ToListAsync(); + + TestOutput.WriteLine(received.Count.ToString()); + TestOutput.WriteLines(received.Take(10)); + + Assert.Equivalent(messages.Count, received.Count); + Assert.Equivalent(messages, received); + Assert.Equivalent(messages.Select(message => message.Data), received.Select(message => message.Data)); + Assert.Equivalent(messages.Select(message => message.Data.Metadata), received.Select(message => message.Data.Metadata)); + } + } +} diff --git a/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/EventDriven/RabbitMqEventBusJsonSerializerContextTest.cs b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/EventDriven/RabbitMqEventBusJsonSerializerContextTest.cs new file mode 100644 index 0000000..8158849 --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/EventDriven/RabbitMqEventBusJsonSerializerContextTest.cs @@ -0,0 +1,298 @@ +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting; +using Cuemon; +using Cuemon.Extensions; +using Cuemon.Threading; +using Microsoft.Extensions.DependencyInjection; +using Savvyio.EventDriven; +using Savvyio.EventDriven.Messaging; +using Savvyio.EventDriven.Messaging.CloudEvents; +using Savvyio.EventDriven.Messaging.CloudEvents.Cryptography; +using Savvyio.Extensions.DependencyInjection; +using Savvyio.Extensions.DependencyInjection.Messaging; +using Savvyio.Extensions.RabbitMQ.Assets; +using Savvyio.Extensions.Text.Json; +using Savvyio.Messaging; +using Savvyio.Messaging.Cryptography; +using System.Linq; +using System.Threading.Channels; +using System.Threading.Tasks; +using Cuemon.Extensions.IO; +using Xunit; +using Xunit.Abstractions; + +namespace Savvyio.Extensions.RabbitMQ.EventDriven +{ + public class RabbitMqEventBusJsonSerializerContextTest : Test + { + public RabbitMqEventBusJsonSerializerContextTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_OneTime() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new MemberCreated("John Doe", "jd@outlook.com"); + var urn = "urn:member-events-one".ToUri(); + var message = member.ToMessage(urn, $"{nameof(MemberCreated)}.updated-event"); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + TestOutput.WriteLine(marshaller.Serialize(message).ToEncodedString()); + + var handlerInvocations = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations++; + await receivedMessages.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await bus.PublishAsync(message).ConfigureAwait(false); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync(); + + Assert.Equal(1, handlerInvocations); + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_OneTime_Signed() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new MemberCreated("John Doe", "jd@outlook.com"); + var urn = "urn:member-events-one".ToUri(); + var message = member.ToMessage(urn, $"{nameof(MemberCreated)}.updated-event.signed").Sign(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + TestOutput.WriteLine(marshaller.Serialize(message).ToEncodedString()); + + var handlerInvocations = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations++; + await receivedMessages.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await bus.PublishAsync(message).ConfigureAwait(false); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync() as ISignedMessage; + received?.CheckSignature(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + + Assert.Equal(1, handlerInvocations); + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + Assert.Equivalent(message.Signature, received.Signature); + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_OneTime_CloudEvent() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new MemberCreated("John Doe", "jd@outlook.com"); + var urn = "urn:member-cloud-events-one".ToUri(); + var message = member.ToMessage(urn, $"{nameof(MemberCreated)}.updated-event.cloud-event").ToCloudEvent(); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + TestOutput.WriteLine(marshaller.Serialize(message).ToEncodedString()); + + var handlerInvocations = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations++; + await receivedMessages.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await bus.PublishAsync(message); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync() as ICloudEvent; + + Assert.Equal(1, handlerInvocations); + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + Assert.Equivalent(message.Specversion, received.Specversion); + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_OneTime_CloudEvent_Signed() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new MemberCreated("John Doe", "jd@outlook.com"); + var urn = "urn:member-events-one".ToUri(); + var message = member.ToMessage(urn, $"{nameof(MemberCreated)}.updated-event.signed-cloud-event").ToCloudEvent().SignCloudEvent(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + TestOutput.WriteLine(marshaller.Serialize(message).ToEncodedString()); + + var handlerInvocations = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations++; + await receivedMessages.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await bus.PublishAsync(message); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync() as ISignedCloudEvent; + + Assert.Equal(1, handlerInvocations); + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + Assert.Equivalent(message.Specversion, received.Specversion); + Assert.Equivalent(message.Signature, received.Signature); + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_HundredTimes() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var messages = Generate.RangeOf(100, _ => + { + var email = $"{Generate.RandomString(5)}@outlook.com"; + return new MemberCreated(Generate.RandomString(10), email).ToMessage("urn:member-events-many".ToUri(), $"{nameof(MemberCreated)}"); + }).ToList(); + var receivedMessages1 = Channel.CreateUnbounded>(); + var receivedMessages2 = Channel.CreateUnbounded>(); + + var handlerInvocations1 = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations1++; + await receivedMessages1.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + var handlerInvocations2 = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations2++; + await receivedMessages2.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await ParallelFactory.ForEachAsync(messages, (message, token) => + { + return bus.PublishAsync(message, o => o.CancellationToken = token); + }).ConfigureAwait(false); + + await Task.Delay(750); + + receivedMessages1.Writer.Complete(); // mark channel write is complete + receivedMessages2.Writer.Complete(); // mark channel write is complete + + var received1 = await receivedMessages1.Reader.ReadAllAsync().ToListAsync(); + var received2 = await receivedMessages2.Reader.ReadAllAsync().ToListAsync(); + + TestOutput.WriteLine(received1.Count.ToString()); + TestOutput.WriteLines(received1.Take(10).Select(m => marshaller.Serialize(m).ToEncodedString())); + + Assert.Equal(100, handlerInvocations1); + Assert.Equal(100, handlerInvocations2); + Assert.Equivalent(messages.Count, received1.Count); + Assert.Equivalent(messages, received1); + Assert.Equivalent(messages, received2); + Assert.Equivalent(messages.Select(message => message.Data), received1.Select(message => message.Data)); + Assert.Equivalent(messages.Select(message => message.Data.Metadata), received1.Select(message => message.Data.Metadata)); + Assert.Equivalent(messages.Select(message => message.Data), received2.Select(message => message.Data)); + Assert.Equivalent(messages.Select(message => message.Data.Metadata), received2.Select(message => message.Data.Metadata)); + } + } +} diff --git a/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/EventDriven/RabbitMqEventBusNewtonsoftJsonSerializerContextTest.cs b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/EventDriven/RabbitMqEventBusNewtonsoftJsonSerializerContextTest.cs new file mode 100644 index 0000000..d38d6c8 --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/EventDriven/RabbitMqEventBusNewtonsoftJsonSerializerContextTest.cs @@ -0,0 +1,298 @@ +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting; +using Cuemon; +using Cuemon.Extensions; +using Cuemon.Extensions.IO; +using Cuemon.Threading; +using Microsoft.Extensions.DependencyInjection; +using Savvyio.EventDriven; +using Savvyio.EventDriven.Messaging; +using Savvyio.EventDriven.Messaging.CloudEvents; +using Savvyio.EventDriven.Messaging.CloudEvents.Cryptography; +using Savvyio.Extensions.DependencyInjection; +using Savvyio.Extensions.DependencyInjection.Messaging; +using Savvyio.Extensions.Newtonsoft.Json; +using Savvyio.Extensions.RabbitMQ.Assets; +using Savvyio.Messaging; +using Savvyio.Messaging.Cryptography; +using System.Linq; +using System.Threading.Channels; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace Savvyio.Extensions.RabbitMQ.EventDriven +{ + public class RabbitMqEventBusNewtonsoftJsonSerializerContextTest : Test + { + public RabbitMqEventBusNewtonsoftJsonSerializerContextTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_OneTime() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new MemberCreated("John Doe", "jd@outlook.com"); + var urn = "urn:member-events-one".ToUri(); + var message = member.ToMessage(urn, $"{nameof(MemberCreated)}.updated-event"); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + TestOutput.WriteLine(marshaller.Serialize(message).ToEncodedString()); + + var handlerInvocations = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations++; + await receivedMessages.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await bus.PublishAsync(message).ConfigureAwait(false); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync(); + + Assert.Equal(1, handlerInvocations); + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_OneTime_Signed() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new MemberCreated("John Doe", "jd@outlook.com"); + var urn = "urn:member-events-one".ToUri(); + var message = member.ToMessage(urn, $"{nameof(MemberCreated)}.updated-event.signed").Sign(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + TestOutput.WriteLine(marshaller.Serialize(message).ToEncodedString()); + + var handlerInvocations = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations++; + await receivedMessages.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await bus.PublishAsync(message).ConfigureAwait(false); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync() as ISignedMessage; + received?.CheckSignature(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + + Assert.Equal(1, handlerInvocations); + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + Assert.Equivalent(message.Signature, received.Signature); + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_OneTime_CloudEvent() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new MemberCreated("John Doe", "jd@outlook.com"); + var urn = "urn:member-events-one".ToUri(); + var message = member.ToMessage(urn, $"{nameof(MemberCreated)}.updated-event.cloud-event").ToCloudEvent(); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + TestOutput.WriteLine(marshaller.Serialize(message).ToEncodedString()); + + var handlerInvocations = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations++; + await receivedMessages.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await bus.PublishAsync(message); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync() as ICloudEvent; + + Assert.Equal(1, handlerInvocations); + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + Assert.Equivalent(message.Specversion, received.Specversion); + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_OneTime_CloudEvent_Signed() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var member = new MemberCreated("John Doe", "jd@outlook.com"); + var urn = "urn:member-events-one".ToUri(); + var message = member.ToMessage(urn, $"{nameof(MemberCreated)}.updated-event.signed-cloud-event").ToCloudEvent().SignCloudEvent(marshaller, o => o.SignatureSecret = new byte[] { 1, 2, 3 }); + var receivedMessages = Channel.CreateUnbounded>(); + + TestOutput.WriteLine(marshaller.Serialize(urn).ToEncodedString()); + TestOutput.WriteLine(marshaller.Serialize(message).ToEncodedString()); + + var handlerInvocations = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations++; + await receivedMessages.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await bus.PublishAsync(message); + + await Task.Delay(200); + + receivedMessages.Writer.Complete(); // mark channel write is complete + + var received = await receivedMessages.Reader.ReadAsync() as ISignedCloudEvent; + + Assert.Equal(1, handlerInvocations); + Assert.Equivalent(message.Data, received.Data); + Assert.Equivalent(message.Time, received.Time); + Assert.Equivalent(message.Source, received.Source); + Assert.Equivalent(message.Id, received.Id); + Assert.Equivalent(message.Type, received.Type); + Assert.Equivalent(message.Specversion, received.Specversion); + Assert.Equivalent(message.Signature, received.Signature); + } + + [Fact] + public async Task SubscribeAndPublishAsync_MemberCreated_HundredTimes() + { + var managed = HostTestFactory.Create(services => + { + services.AddMarshaller(); + services.AddMessageBus(o => o.Lifetime = ServiceLifetime.Singleton).AddConfiguredOptions(o => o.ExchangeName = Generate.RandomString(10)); + }); + + var bus = managed.Host.Services.GetRequiredService(); + var marshaller = managed.Host.Services.GetRequiredService(); + + var messages = Generate.RangeOf(100, _ => + { + var email = $"{Generate.RandomString(5)}@outlook.com"; + return new MemberCreated(Generate.RandomString(10), email).ToMessage("urn:member-events-many".ToUri(), $"{nameof(MemberCreated)}"); + }).ToList(); + var receivedMessages1 = Channel.CreateUnbounded>(); + var receivedMessages2 = Channel.CreateUnbounded>(); + + var handlerInvocations1 = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations1++; + await receivedMessages1.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + var handlerInvocations2 = 0; + Task.Run(async () => + { + await bus.SubscribeAsync(async (msg, token) => + { + handlerInvocations2++; + await receivedMessages2.Writer.WriteAsync(msg, token).ConfigureAwait(false); + }).ConfigureAwait(false); + }); + + await Task.Delay(200); // wait briefly to ensure subscription setup + + await ParallelFactory.ForEachAsync(messages, (message, token) => + { + return bus.PublishAsync(message, o => o.CancellationToken = token); + }).ConfigureAwait(false); + + await Task.Delay(750); + + receivedMessages1.Writer.Complete(); // mark channel write is complete + receivedMessages2.Writer.Complete(); // mark channel write is complete + + var received1 = await receivedMessages1.Reader.ReadAllAsync().ToListAsync(); + var received2 = await receivedMessages2.Reader.ReadAllAsync().ToListAsync(); + + TestOutput.WriteLine(received1.Count.ToString()); + TestOutput.WriteLines(received1.Take(10)); + + Assert.Equal(100, handlerInvocations1); + Assert.Equal(100, handlerInvocations2); + Assert.Equivalent(messages.Count, received1.Count); + Assert.Equivalent(messages, received1); + Assert.Equivalent(messages, received2); + Assert.Equivalent(messages.Select(message => message.Data), received1.Select(message => message.Data)); + Assert.Equivalent(messages.Select(message => message.Data.Metadata), received1.Select(message => message.Data.Metadata)); + Assert.Equivalent(messages.Select(message => message.Data), received2.Select(message => message.Data)); + Assert.Equivalent(messages.Select(message => message.Data.Metadata), received2.Select(message => message.Data.Metadata)); + } + } +} diff --git a/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Savvyio.Extensions.RabbitMQ.FunctionalTests.csproj b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Savvyio.Extensions.RabbitMQ.FunctionalTests.csproj new file mode 100644 index 0000000..0c0b39c --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.FunctionalTests/Savvyio.Extensions.RabbitMQ.FunctionalTests.csproj @@ -0,0 +1,21 @@ + + + + Savvyio.Extensions.RabbitMQ + + + + + + + + + + + + + + + + + From 1bd57e44cf1ac0b0105579f7df292a6344c7bbe4 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sat, 7 Jun 2025 22:59:56 +0200 Subject: [PATCH 03/16] :sparkles: support for RabbitMQ --- Savvyio.sln | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Savvyio.sln b/Savvyio.sln index 1f41676..fb3589a 100644 --- a/Savvyio.sln +++ b/Savvyio.sln @@ -119,6 +119,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Savvyio.Extensions.QueueSto EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Savvyio.Extensions.DependencyInjection.QueueStorage", "src\Savvyio.Extensions.DependencyInjection.QueueStorage\Savvyio.Extensions.DependencyInjection.QueueStorage.csproj", "{36520BC5-4343-4CF3-A8AE-B7A04B91DDB2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Savvyio.Extensions.RabbitMQ", "src\Savvyio.Extensions.RabbitMQ\Savvyio.Extensions.RabbitMQ.csproj", "{0AB0316F-76C4-413F-8C96-DB3489E318E6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Savvyio.Extensions.RabbitMQ.FunctionalTests", "test\Savvyio.Extensions.RabbitMQ.FunctionalTests\Savvyio.Extensions.RabbitMQ.FunctionalTests.csproj", "{C15021DF-E983-4B40-8F65-16A8966429AF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -349,6 +353,14 @@ Global {36520BC5-4343-4CF3-A8AE-B7A04B91DDB2}.Debug|Any CPU.Build.0 = Debug|Any CPU {36520BC5-4343-4CF3-A8AE-B7A04B91DDB2}.Release|Any CPU.ActiveCfg = Release|Any CPU {36520BC5-4343-4CF3-A8AE-B7A04B91DDB2}.Release|Any CPU.Build.0 = Release|Any CPU + {0AB0316F-76C4-413F-8C96-DB3489E318E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0AB0316F-76C4-413F-8C96-DB3489E318E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0AB0316F-76C4-413F-8C96-DB3489E318E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0AB0316F-76C4-413F-8C96-DB3489E318E6}.Release|Any CPU.Build.0 = Release|Any CPU + {C15021DF-E983-4B40-8F65-16A8966429AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C15021DF-E983-4B40-8F65-16A8966429AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C15021DF-E983-4B40-8F65-16A8966429AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C15021DF-E983-4B40-8F65-16A8966429AF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -410,6 +422,8 @@ Global {04804591-413B-4199-90E6-723097091DF9} = {407762FB-26D8-435F-AE16-C76791EC9FEC} {0F265E4A-04AD-48F0-B309-22492822D91C} = {407762FB-26D8-435F-AE16-C76791EC9FEC} {36520BC5-4343-4CF3-A8AE-B7A04B91DDB2} = {0E75F0C5-DBEB-4B6D-AC52-98656CA79A7D} + {0AB0316F-76C4-413F-8C96-DB3489E318E6} = {0E75F0C5-DBEB-4B6D-AC52-98656CA79A7D} + {C15021DF-E983-4B40-8F65-16A8966429AF} = {407762FB-26D8-435F-AE16-C76791EC9FEC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D8DDAD51-08E6-42B5-970B-2DC88D44297B} From 312659f71fbd5881e45e7f10145365c3252d576d Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Sat, 7 Jun 2025 23:00:11 +0200 Subject: [PATCH 04/16] :arrow_up: bump dependencies --- Directory.Packages.props | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 728f220..719984a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,13 +4,13 @@ true - - + + - + @@ -22,9 +22,10 @@ - - + + + @@ -32,7 +33,7 @@ - + From c06ec5a493712a0046da1a0b55c9488a85400835 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:39:38 +0200 Subject: [PATCH 05/16] :construction_worker: include integration test for rabbitmq --- .github/workflows/pipelines.yml | 42 ++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pipelines.yml b/.github/workflows/pipelines.yml index 664b616..f4cf098 100644 --- a/.github/workflows/pipelines.yml +++ b/.github/workflows/pipelines.yml @@ -40,6 +40,7 @@ jobs: !test/**/Savvyio.FunctionalTests.csproj !test/**/Savvyio.Extensions.SimpleQueueService.FunctionalTests.csproj !test/**/Savvyio.Extensions.QueueStorage.FunctionalTests.csproj + !test/**/Savvyio.Extensions.RabbitMQ.FunctionalTests.csproj - name: JSON output run: echo "${{ steps.test-projects.outputs.result }}" @@ -49,7 +50,7 @@ jobs: strategy: matrix: configuration: [Debug, Release] - uses: codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@v1 + uses: codebeltnet/jobs-dotnet-build/.github/workflows/default.yml@v2 with: configuration: ${{ matrix.configuration }} strong-name-key-filename: savvyio.snk @@ -61,7 +62,7 @@ jobs: strategy: matrix: configuration: [Debug, Release] - uses: codebeltnet/jobs-dotnet-pack/.github/workflows/default.yml@v1 + uses: codebeltnet/jobs-dotnet-pack/.github/workflows/default.yml@v2 with: configuration: ${{ matrix.configuration }} upload-packed-artifact: true @@ -76,7 +77,7 @@ jobs: os: [ubuntu-24.04, windows-2022] configuration: [Debug, Release] project: ${{ fromJson(needs.prepare_test.outputs.json) }} - uses: codebeltnet/jobs-dotnet-test/.github/workflows/default.yml@v1 + uses: codebeltnet/jobs-dotnet-test/.github/workflows/default.yml@v2 with: runs-on: ${{ matrix.os }} configuration: ${{ matrix.configuration }} @@ -84,7 +85,7 @@ jobs: build-switches: -p:SkipSignAssembly=true integration_test: - name: 🧪 Test + name: ⚗️ Integration Test - Azure and AWS needs: [build] strategy: fail-fast: false @@ -104,11 +105,11 @@ jobs: uses: codebeltnet/dotnet-tool-install-reportgenerator@v1 - name: Test with ${{ matrix.configuration }} build - uses: codebeltnet/dotnet-test@v3 + uses: codebeltnet/dotnet-test@v4 with: projects: ${{ matrix.project }} configuration: ${{ matrix.configuration }} - buildSwitches: -p:SkipSignAssembly=true + build-switches: -p:SkipSignAssembly=true level: normal env: AWS__CALLERIDENTITY: ${{ secrets.AWS_CALLER_IDENTITY }} @@ -125,6 +126,35 @@ jobs: AZURE__EVENTGRID__LINUX__DEBUG__KEY: ${{ secrets.AZURE_EVENTGRID_LINUX_DEBUG_KEY }} AZURE__EVENTGRID__LINUX__RELEASE__KEY: ${{ secrets.AZURE_EVENTGRID_LINUX_RELEASE_KEY }} + integration_test_rabbitmq: + name: ⚗️ Integration Test - RabbitMQ + needs: [build] + runs-on: ubuntu-24.04 + timeout-minutes: 15 + steps: + - name: Checkout + uses: codebeltnet/git-checkout@v1 + + - name: Install .NET + uses: codebeltnet/install-dotnet@v2 + + - name: Install .NET Tool - Report Generator + uses: codebeltnet/dotnet-tool-install-reportgenerator@v1 + + - name: Spin up RabbitMQ test dependency + run: | + docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management + + - name: Test with Release build + uses: codebeltnet/dotnet-test@v4 + with: + projects: test/**/Savvyio.Extensions.RabbitMQ.FunctionalTests.csproj + + - name: Stop RabbitMQ + run: | + docker stop --name rabbitmq + docker rm --name rabbitmq + sonarcloud: name: call-sonarcloud needs: [build, test, integration_test] From af60cee08217f74db06363b8130e2920092f0eac Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:41:05 +0200 Subject: [PATCH 06/16] :package: updated NuGet package definition --- .nuget/Savvyio.App/PackageReleaseNotes.txt | 32 +++++++++++++ .nuget/Savvyio.App/README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Commands.Messaging/README.md | 2 + .../Savvyio.Commands/PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Commands/README.md | 2 + .nuget/Savvyio.Core/PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Core/README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Domain.EventSourcing/README.md | 10 +++- .nuget/Savvyio.Domain/PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Domain/README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../Savvyio.EventDriven.Messaging/README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.EventDriven/README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Extensions.Dapper/README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 10 ++++ .../README.md | 45 ++++++++++++++++++ .../icon.png | Bin 0 -> 3693 bytes .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../Savvyio.Extensions.Dispatchers/README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Extensions.EFCore/README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .../Savvyio.Extensions.QueueStorage/README.md | 2 + .../PackageReleaseNotes.txt | 14 ++++++ .nuget/Savvyio.Extensions.RabbitMQ/README.md | 45 ++++++++++++++++++ .nuget/Savvyio.Extensions.RabbitMQ/icon.png | Bin 0 -> 3693 bytes .../PackageReleaseNotes.txt | 6 +++ .../README.md | 2 + .../PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Extensions.Text.Json/README.md | 2 + .../Savvyio.Messaging/PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Messaging/README.md | 2 + .../Savvyio.Queries/PackageReleaseNotes.txt | 6 +++ .nuget/Savvyio.Queries/README.md | 2 + 64 files changed, 378 insertions(+), 2 deletions(-) create mode 100644 .nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/PackageReleaseNotes.txt create mode 100644 .nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/README.md create mode 100644 .nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/icon.png create mode 100644 .nuget/Savvyio.Extensions.RabbitMQ/PackageReleaseNotes.txt create mode 100644 .nuget/Savvyio.Extensions.RabbitMQ/README.md create mode 100644 .nuget/Savvyio.Extensions.RabbitMQ/icon.png diff --git a/.nuget/Savvyio.App/PackageReleaseNotes.txt b/.nuget/Savvyio.App/PackageReleaseNotes.txt index c653331..f1dd3c9 100644 --- a/.nuget/Savvyio.App/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.App/PackageReleaseNotes.txt @@ -1,3 +1,35 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# References +- Savvyio +- Savvyio.Commands +- Savvyio.Commands.Messaging +- Savvyio.Domain +- Savvyio.Domain.EventSourcing +- Savvyio.EventDriven +- Savvyio.EventDriven.Messaging +- Savvyio.Extensions.Dapper +- Savvyio.Extensions.DependencyInjection +- Savvyio.Extensions.DependencyInjection.Dapper +- Savvyio.Extensions.DependencyInjection.Domain +- Savvyio.Extensions.DependencyInjection.EFCore +- Savvyio.Extensions.DependencyInjection.EFCore.Domain +- Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing +- Savvyio.Extensions.DependencyInjection.QueueStorage +- Savvyio.Extensions.DependencyInjection.RabbitMQ +- Savvyio.Extensions.DependencyInjection.SimpleQueueService +- Savvyio.Extensions.Dispatchers +- Savvyio.Extensions.EFCore +- Savvyio.Extensions.EFCore.Domain +- Savvyio.Extensions.EFCore.Domain.EventSourcing +- Savvyio.Extensions.QueueStorage +- Savvyio.Extensions.RabbitMQ +- Savvyio.Extensions.SimpleQueueService +- Savvyio.Extensions.Text.Json +- Savvyio.Messaging +- Savvyio.Queries +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.App/README.md b/.nuget/Savvyio.App/README.md index dcd53ea..e8657d3 100644 --- a/.nuget/Savvyio.App/README.md +++ b/.nuget/Savvyio.App/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Commands.Messaging/PackageReleaseNotes.txt b/.nuget/Savvyio.Commands.Messaging/PackageReleaseNotes.txt index 28dadf4..df0b13b 100644 --- a/.nuget/Savvyio.Commands.Messaging/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Commands.Messaging/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Commands.Messaging/README.md b/.nuget/Savvyio.Commands.Messaging/README.md index ece2b6a..94b1c5b 100644 --- a/.nuget/Savvyio.Commands.Messaging/README.md +++ b/.nuget/Savvyio.Commands.Messaging/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Commands/PackageReleaseNotes.txt b/.nuget/Savvyio.Commands/PackageReleaseNotes.txt index a92c361..5781439 100644 --- a/.nuget/Savvyio.Commands/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Commands/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Commands/README.md b/.nuget/Savvyio.Commands/README.md index daa99cd..6b6dc3b 100644 --- a/.nuget/Savvyio.Commands/README.md +++ b/.nuget/Savvyio.Commands/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Core/PackageReleaseNotes.txt b/.nuget/Savvyio.Core/PackageReleaseNotes.txt index c1c21b0..e642bb0 100644 --- a/.nuget/Savvyio.Core/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Core/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Core/README.md b/.nuget/Savvyio.Core/README.md index be9132a..0331b95 100644 --- a/.nuget/Savvyio.Core/README.md +++ b/.nuget/Savvyio.Core/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Domain.EventSourcing/PackageReleaseNotes.txt b/.nuget/Savvyio.Domain.EventSourcing/PackageReleaseNotes.txt index 612a781..ed8984e 100644 --- a/.nuget/Savvyio.Domain.EventSourcing/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Domain.EventSourcing/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Domain.EventSourcing/README.md b/.nuget/Savvyio.Domain.EventSourcing/README.md index b89de8b..0eabba4 100644 --- a/.nuget/Savvyio.Domain.EventSourcing/README.md +++ b/.nuget/Savvyio.Domain.EventSourcing/README.md @@ -14,10 +14,12 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.App](https://www.nuget.org/packages/Savvyio.App/) 🏭 * [Savvyio.Commands](https://www.nuget.org/packages/Savvyio.Commands/) 📦 +* [Savvyio.Commands.Messaging](https://www.nuget.org/packages/Savvyio.Commands.Messaging/) 📦 * [Savvyio.Core](https://www.nuget.org/packages/Savvyio.Core/) 📦 * [Savvyio.Domain](https://www.nuget.org/packages/Savvyio.Domain/) 📦 * [Savvyio.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Domain.EventSourcing/) 📦 * [Savvyio.EventDriven](https://www.nuget.org/packages/Savvyio.EventDriven/) 📦 +* [Savvyio.EventDriven.Messaging](https://www.nuget.org/packages/Savvyio.EventDriven.Messaging/) 📦 * [Savvyio.Extensions.Dapper](https://www.nuget.org/packages/Savvyio.Extensions.Dapper/) 📦 * [Savvyio.Extensions.DapperExtensions](https://www.nuget.org/packages/Savvyio.Extensions.DapperExtensions/) 📦 * [Savvyio.Extensions.DependencyInjection](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection/) 📦 @@ -27,13 +29,17 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 +* [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 * [Savvyio.Extensions.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain/) 📦 * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 +* [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 -* [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 -* [Savvyio.Queries](https://www.nuget.org/packages/Savvyio.Queries/) 📦 \ No newline at end of file +* [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 +* [Savvyio.Queries](https://www.nuget.org/packages/Savvyio.Queries/) 📦 diff --git a/.nuget/Savvyio.Domain/PackageReleaseNotes.txt b/.nuget/Savvyio.Domain/PackageReleaseNotes.txt index c669eb5..c982c5b 100644 --- a/.nuget/Savvyio.Domain/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Domain/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Domain/README.md b/.nuget/Savvyio.Domain/README.md index 59019a6..3739c3e 100644 --- a/.nuget/Savvyio.Domain/README.md +++ b/.nuget/Savvyio.Domain/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.EventDriven.Messaging/PackageReleaseNotes.txt b/.nuget/Savvyio.EventDriven.Messaging/PackageReleaseNotes.txt index 3e6a265..5e8245e 100644 --- a/.nuget/Savvyio.EventDriven.Messaging/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.EventDriven.Messaging/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.EventDriven.Messaging/README.md b/.nuget/Savvyio.EventDriven.Messaging/README.md index 3e04a02..da19638 100644 --- a/.nuget/Savvyio.EventDriven.Messaging/README.md +++ b/.nuget/Savvyio.EventDriven.Messaging/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.EventDriven/PackageReleaseNotes.txt b/.nuget/Savvyio.EventDriven/PackageReleaseNotes.txt index efcd9b9..3592b0c 100644 --- a/.nuget/Savvyio.EventDriven/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.EventDriven/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.EventDriven/README.md b/.nuget/Savvyio.EventDriven/README.md index a290772..176761e 100644 --- a/.nuget/Savvyio.EventDriven/README.md +++ b/.nuget/Savvyio.EventDriven/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.Dapper/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.Dapper/PackageReleaseNotes.txt index c83a707..57d1716 100644 --- a/.nuget/Savvyio.Extensions.Dapper/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.Dapper/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.Dapper/README.md b/.nuget/Savvyio.Extensions.Dapper/README.md index 4d5f6e3..fbdbb84 100644 --- a/.nuget/Savvyio.Extensions.Dapper/README.md +++ b/.nuget/Savvyio.Extensions.Dapper/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DapperExtensions/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DapperExtensions/PackageReleaseNotes.txt index 20d07ad..b2cdefe 100644 --- a/.nuget/Savvyio.Extensions.DapperExtensions/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DapperExtensions/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DapperExtensions/README.md b/.nuget/Savvyio.Extensions.DapperExtensions/README.md index b9a4b6e..6f93fbd 100644 --- a/.nuget/Savvyio.Extensions.DapperExtensions/README.md +++ b/.nuget/Savvyio.Extensions.DapperExtensions/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.Dapper/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection.Dapper/PackageReleaseNotes.txt index 303043c..838a462 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.Dapper/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DependencyInjection.Dapper/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.Dapper/README.md b/.nuget/Savvyio.Extensions.DependencyInjection.Dapper/README.md index 2ea2ca9..7e224db 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.Dapper/README.md +++ b/.nuget/Savvyio.Extensions.DependencyInjection.Dapper/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.DapperExtensions/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection.DapperExtensions/PackageReleaseNotes.txt index 4dc3743..68b3a54 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.DapperExtensions/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DependencyInjection.DapperExtensions/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.DapperExtensions/README.md b/.nuget/Savvyio.Extensions.DependencyInjection.DapperExtensions/README.md index 295f621..2b671b6 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.DapperExtensions/README.md +++ b/.nuget/Savvyio.Extensions.DependencyInjection.DapperExtensions/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.Domain/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection.Domain/PackageReleaseNotes.txt index 1a4e425..7196638 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.Domain/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DependencyInjection.Domain/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.Domain/README.md b/.nuget/Savvyio.Extensions.DependencyInjection.Domain/README.md index c96379e..439c5ad 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.Domain/README.md +++ b/.nuget/Savvyio.Extensions.DependencyInjection.Domain/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/PackageReleaseNotes.txt index a6e4ef8..316fd7a 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/README.md b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/README.md index 503bbf1..d886616 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/README.md +++ b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain/PackageReleaseNotes.txt index 621c553..07e54b4 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain/README.md b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain/README.md index ef1fd1c..62c24ee 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain/README.md +++ b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore.Domain/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore/PackageReleaseNotes.txt index f60a702..b19c34f 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore/README.md b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore/README.md index 313a03f..e5df7f4 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.EFCore/README.md +++ b/.nuget/Savvyio.Extensions.DependencyInjection.EFCore/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.QueueStorage/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection.QueueStorage/PackageReleaseNotes.txt index cb0a1ef..06b9f7c 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.QueueStorage/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DependencyInjection.QueueStorage/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.QueueStorage/README.md b/.nuget/Savvyio.Extensions.DependencyInjection.QueueStorage/README.md index 07db249..6c24396 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.QueueStorage/README.md +++ b/.nuget/Savvyio.Extensions.DependencyInjection.QueueStorage/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/PackageReleaseNotes.txt new file mode 100644 index 0000000..25db5a9 --- /dev/null +++ b/.nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/PackageReleaseNotes.txt @@ -0,0 +1,10 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# New Features +- ADDED RabbitMqCommandQueue{TMarker} class in the Savvyio.Extensions.DependencyInjection.RabbitMQ.Commands namespace that provides default implementation of the RabbitMqMessage class for messages holding an ICommand implementation +- ADDED RabbitMqCommandQueueOptions{TMarker} class in the Savvyio.Extensions.DependencyInjection.RabbitMQ.Commands namespace that provides configuration options for RabbitMqCommandQueue{TMarker} +- ADDED RabbitMqEventBus{TMarker} class in the Savvyio.Extensions.DependencyInjection.RabbitMQ.EventDriven namespace that provides a default implementation of the RabbitMqMessage class for messages holding an IIntegrationEvent implementation +- ADDED RabbitMqEventBusOptions{TMarker} class in the Savvyio.Extensions.DependencyInjection.RabbitMQ.EventDriven namespace that provides configuration options for RabbitMqEventBus{TMarker} +- ADDED ServiceCollectionExtensions class in the Savvyio.Extensions.DependencyInjection.RabbitMQ namespace that consist of extension methods for the IServiceCollection interface: AddRabbitMqCommandQueue, AddRabbitMqEventBus +  \ No newline at end of file diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/README.md b/.nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/README.md new file mode 100644 index 0000000..2d47050 --- /dev/null +++ b/.nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/README.md @@ -0,0 +1,45 @@ +# Savvyio.Extensions.DependencyInjection.RabbitMQ + +Extend the Savvy I/O support for Microsoft Dependency Injection with RabbitMQ Worker Queue and Publish/Subscribe implementations. + +## About + +An open-source project (MIT license) that provides a SOLID and clean .NET class library for writing DDD, CQRS and Event Sourcing applications. + +![Savvy I/O Flow](https://raw.githubusercontent.com/codebeltnet/savvyio/main/.assets/savvyio.png) + +It is, by heart, free, flexible and built to extend and boost your agile codebelt. + +## Related Packages + +* [Savvyio.App](https://www.nuget.org/packages/Savvyio.App/) 🏭 +* [Savvyio.Commands](https://www.nuget.org/packages/Savvyio.Commands/) 📦 +* [Savvyio.Commands.Messaging](https://www.nuget.org/packages/Savvyio.Commands.Messaging/) 📦 +* [Savvyio.Core](https://www.nuget.org/packages/Savvyio.Core/) 📦 +* [Savvyio.Domain](https://www.nuget.org/packages/Savvyio.Domain/) 📦 +* [Savvyio.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Domain.EventSourcing/) 📦 +* [Savvyio.EventDriven](https://www.nuget.org/packages/Savvyio.EventDriven/) 📦 +* [Savvyio.EventDriven.Messaging](https://www.nuget.org/packages/Savvyio.EventDriven.Messaging/) 📦 +* [Savvyio.Extensions.Dapper](https://www.nuget.org/packages/Savvyio.Extensions.Dapper/) 📦 +* [Savvyio.Extensions.DapperExtensions](https://www.nuget.org/packages/Savvyio.Extensions.DapperExtensions/) 📦 +* [Savvyio.Extensions.DependencyInjection](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection/) 📦 +* [Savvyio.Extensions.DependencyInjection.Dapper](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Dapper/) 📦 +* [Savvyio.Extensions.DependencyInjection.DapperExtensions](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.DapperExtensions/) 📦 +* [Savvyio.Extensions.DependencyInjection.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Domain/) 📦 +* [Savvyio.Extensions.DependencyInjection.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore/) 📦 +* [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 +* [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 +* [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 +* [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 +* [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 +* [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 +* [Savvyio.Extensions.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain/) 📦 +* [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 +* [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 +* [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 +* [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 +* [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 +* [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 +* [Savvyio.Queries](https://www.nuget.org/packages/Savvyio.Queries/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/icon.png b/.nuget/Savvyio.Extensions.DependencyInjection.RabbitMQ/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..39600eaba64d060833613a50a133ad42af9222eb GIT binary patch literal 3693 zcmZXXc{CJk`^WDYgRy0QD36^;c6wxqv72mV-?D~e8C%8@X6!sF4I;!8LZm|38B3&$ zy)2`_Bt(|UNY;Ly_jk_k{NDHdcDq z7@Xnc?9ul4aN?MPO&r4jfbjog5D^Ph+DY(qxS>P1HOeO(?Gfq?&}g*0Uyy&8mq)O- zJSx<;a6{|NNydGofv!zt(fXs9aGQ_q{hgh$K4;lIMc~h^Zi%wDBN>{s8sxk6_nYjS zd7g0H^uO}V)ur1I=jn6SA%m)`%uOa&=gNq!)bZz3x~w}rchcV)rO@Fp1 z#m$FdaYy1RA+Dm?1J{SlhK>(&i|U0tFCDbTceW2}vwQj&Bz{~df~C-9I)V<5d3wWz zozxG4=2v;8N9k9qL7jb`o3zdT1tmE~JnT^r^i_Rn;Jc;1=jSy%eaf#B(j36}#*EJf z|4c(BRvGBWAmjcd6r@}}koPfI_LK+_6@xegevNW}MVAyp))#cY&8qhYMi%hVt{g&q zZrSR4e~Wpg?7-z5%}Z#gtE2sVFu@H{4g|IBH|x+bSn9484u_j*5hM)v@N|iMx1-M! zl0*Obck(E1N;KMZWV$$%6RIf;lq+iFg})tCgsf$pdhEvzjg&Owg!K_KE(<%Gy3`K5 zElk}RzK)b-+WJ?sLBluq;}XZ?2z;&Sh-S&5UEso-#o2TZD*z73`iuKheg_PoCSvkW zPuF2Wj?k*sTLPV*Z+%?Y7PWi>>-Rvys)gSDwXF-|h!L1}Z+p(XJf5~Oz7b`eBCDX6$&nq$u!*u6N63$#c^NHj}*RsSeNc4Ma z7GTWIZ74R;q`Q4v$bic&?csfEE2_Be6d37M^qU2jyp^gt_ua33vj^_4TWeGL1Q7Y7 z`pqxsDCB7S0b>ySwOzm{pJ(@srxOE#r^sR4tn^-u+m7L&lVm#ody?bPTyJGZq}y_# zvHb5fL3bIt;H&u!63P+r}hUb;qu7 z+YVHQsYg^46I*Z?G2ol<;p}__cUbA`UR$N(;<~{U<`}v$5+A)l*ICP^V6k+%gm(fT zPEYDrrly!RQ8J<{di;Jw)}>Qz5V!(T5Jh3w~enBhO>z zAI55=t)Hu^`UtYlI0-etAC%&-x*}Ws_GaIaj2M=)%P!hCDT}-#4NM}3s2g@e+=H7A zfxIuwUfSNh)KW`ZW2o>dXSi>Qml0Xy3T6NfLp~`kQDZiS(clpWynqC;y=zr8ZmQf>Ki|f-p-S`WY)kgOdWWnJd>_dRYwdiIerBH1(%gHhESId>LTa9*0OqUyGHpzG94S-qT4g zguUm$3nV1yV<_u4o@^Ck9XVb)cv1cO7H8M+PY;zvIvce-{$gy7UVXNF{905Lfi+}C zNWsF~;UdJv9l-NRh2vJmun1+%;Ic6ywN9-}T2u(X7TF|V;Ba3Qp#YOUl;D_uS&W4% zKrXU@K?&JQ;SHVpf+|n-qm9DhrZ;0uu&11I74cwF+&|x5i5bIxf7mShk z<*MeMZd(Wu&7APc(Dy8?0vTDN2r0b>*bWW^UQxb?g@>L^1#LH{6G-Zyp;67pE-U5N zMtPw#);;oc?XVOOC5TWvdEPy7VOr&34zF1x4@OGbQiJ=`)AA_o0a7!%Yw}XlzR%A0 zJv{`Tab!{Aih`bzkV>w_T=QlO>NtR0MVGwyLAU!dKC2xt$csKH*Vls)$miomfCgk< z*kjeo>k|~&31@D8NH* zNPc{jT1)C%;5M2pi4($%22jglxk`VU?5BZXn%++Ea}i5UL6{wxl)ucBbC(-dA66Yp{S*YojMN$eYC-RfsDTil@2YPs(7+QGd_ ze>Z~tWMll8<5{QA%4L@-I>x9*gU*ua`5UbX%UX@7r2f)ckKiWXV}OCo^kg`N&M&LQ zLBQNx^KSQUQ2T;^HF4mxAI#^Y{gl7d^tHUoLAQC*T~rNv`UPkyR?zx~QEXs=1eabh zYeC2M*8#oC!YC9Qhk>Sp*w zMm!rXZsbd;hYEUK&OM8Tup;zBh%YJkLh{~6yTb8A#0#pM$RRYd3f$$MvRe-Qez)pt z?7Ujc+_8mb^+Masd>OB_OwnGW39fi|nxL*3QPz^{@fO(i#F*N1Y);4zl?1(3ABMjB zuKoVT&kZG;>(R0TWU|BTrwWGNEOUhkS+S?BJI~w{;5M&A7cz}w%=re!yXuRhsGgrz zJkGYTVL$YZKlHUS64VKa6u>yQ_wy6vv-|7!OYiI+#jE!9GnYnm+%qv4so*mhyxkHl z!x8{h97ktjQ#G_TZOEeqbw#?Ra9Y5l@d(A}dauM$%{gO~*vhtm9wuuKqSCZNpa{G% zLiq$tA9}9y-#9EIM@Xwxw~yqII$furuA0Cj~KUp7CZ z00|f&-HojC+dVEserpAbcla5MnF;eI5dJ^Ufkbh7_h8&j-k08%>so9xxzQv}OIR;8 zm&MnH&1MfNj``QRMn3DZE3-xOXUfIgG&ZWM=VL>1LNhyF^~@)nMDo}SrkNBl#F$gF zHx`F>yXF&!3KL|ZwNP$XfQf!h{zHPf_qOe3)xHrI9HE?bQn)C|jb5>_*#v1hO1j(B z9m$;8)S$jVf5l~Mvts9sC^=xdUgy1K)Q;e3DC=DwOxJy=;zcXKVBCnDubUjYHcpmj zRcYnRNG-|NsWC!nCX5<_-;SSY%G_~cNmy5&Zi3)PU+qZc_$ixqbE?#aC}DDsTC2t> zLOF-FDT#7JX&$CmgUs1IZ7y?I2sh!8g4);9?c1>&)ErH>0OsA?k4@YZ?jfWg}-jt7@dN{T*NFretQudlEpMS<9vRX^0{-GSm;?6;$~c8SrX zY$eaOsQ2%U^PH58r)Y1=J0(ovB4IQ1$<2*gw0+yR!!+9Ku_ncZpG0;07jZvrO_$OR zMvhMPE=r2R@XeZYx+}X3`XY~AG{VC-Hl}$m)c*bS8sEkvLpr0rH0qKg`?1F!T8bEF zF1<7huY38lrKclD^u7rk(xmC6eR%M=v3Al1oj*L5%z;LYOkN!>h^Bmh)uXc>;1_-2 z)Y8u1NgM!71S)9!SiaRbxUPj>^^izYOY@m%C3QqCt(@v-Kd$@sW(NE6+$V`l0PuS@ zrL8{1d%vYP+jJXBkLCJhNdx-v0qNy(bVxlWLTWLY052t%B=G?JJvGJmmAg_N^z)@U zWcP_OVYc+LQ>AyJO8!DpT}QNN!tnr+f~a(<1$vrSl$8UCrZlA+h3zHOrA|j4SEVOAMkC{xzHIiAF$szr|_`m!op% zptu49G@<~1$i#t)^hr8Cl>5}x&0%~#teCw-EkAPksaneI<*|^CFYD&ruX4bL2%^%MF9!pK9c<8eHkLb#QOZ%%G1*%uWPkD2riCq zeHNS*8YRcEP}-ZvYFv6iVo-faHLUx$Ln7x1i59akgkD2`b!{2KG;>Zo2>NUNu%^eX zO~!RcQq@eLjo|bJc7^Fc*VLq?i|L zW6krTGz|4>^e9-x#Q1~k$0cil#)>UW2ps=AZ~XrO|L;2W?|uJ=i2e8FA-BN{w8qhf Swtezd1V}>*gIYcJg#Q5!QPfBP literal 0 HcmV?d00001 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.SimpleQueueService/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection.SimpleQueueService/PackageReleaseNotes.txt index 36e0bf8..22014ad 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.SimpleQueueService/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DependencyInjection.SimpleQueueService/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DependencyInjection.SimpleQueueService/README.md b/.nuget/Savvyio.Extensions.DependencyInjection.SimpleQueueService/README.md index 033d4c7..d8c3784 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection.SimpleQueueService/README.md +++ b/.nuget/Savvyio.Extensions.DependencyInjection.SimpleQueueService/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.DependencyInjection/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.DependencyInjection/PackageReleaseNotes.txt index 49b8d90..4be2e33 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.DependencyInjection/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.DependencyInjection/README.md b/.nuget/Savvyio.Extensions.DependencyInjection/README.md index 8072e37..4cddff4 100644 --- a/.nuget/Savvyio.Extensions.DependencyInjection/README.md +++ b/.nuget/Savvyio.Extensions.DependencyInjection/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.Dispatchers/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.Dispatchers/PackageReleaseNotes.txt index 1c69f99..43d1724 100644 --- a/.nuget/Savvyio.Extensions.Dispatchers/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.Dispatchers/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.Dispatchers/README.md b/.nuget/Savvyio.Extensions.Dispatchers/README.md index 7a32d99..5766f27 100644 --- a/.nuget/Savvyio.Extensions.Dispatchers/README.md +++ b/.nuget/Savvyio.Extensions.Dispatchers/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.EFCore.Domain.EventSourcing/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.EFCore.Domain.EventSourcing/PackageReleaseNotes.txt index 50f17f1..8b58b46 100644 --- a/.nuget/Savvyio.Extensions.EFCore.Domain.EventSourcing/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.EFCore.Domain.EventSourcing/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.EFCore.Domain.EventSourcing/README.md b/.nuget/Savvyio.Extensions.EFCore.Domain.EventSourcing/README.md index 0510840..fc4d0a0 100644 --- a/.nuget/Savvyio.Extensions.EFCore.Domain.EventSourcing/README.md +++ b/.nuget/Savvyio.Extensions.EFCore.Domain.EventSourcing/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.EFCore.Domain/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.EFCore.Domain/PackageReleaseNotes.txt index 42ee849..b05c912 100644 --- a/.nuget/Savvyio.Extensions.EFCore.Domain/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.EFCore.Domain/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.EFCore.Domain/README.md b/.nuget/Savvyio.Extensions.EFCore.Domain/README.md index 44f7f9a..0317917 100644 --- a/.nuget/Savvyio.Extensions.EFCore.Domain/README.md +++ b/.nuget/Savvyio.Extensions.EFCore.Domain/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.EFCore/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.EFCore/PackageReleaseNotes.txt index 2642f1b..5ac622b 100644 --- a/.nuget/Savvyio.Extensions.EFCore/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.EFCore/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.EFCore/README.md b/.nuget/Savvyio.Extensions.EFCore/README.md index fabc23e..90570cd 100644 --- a/.nuget/Savvyio.Extensions.EFCore/README.md +++ b/.nuget/Savvyio.Extensions.EFCore/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.Newtonsoft.Json/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.Newtonsoft.Json/PackageReleaseNotes.txt index 3dd4382..cf39034 100644 --- a/.nuget/Savvyio.Extensions.Newtonsoft.Json/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.Newtonsoft.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.Newtonsoft.Json/README.md b/.nuget/Savvyio.Extensions.Newtonsoft.Json/README.md index 12e3780..8e6f29a 100644 --- a/.nuget/Savvyio.Extensions.Newtonsoft.Json/README.md +++ b/.nuget/Savvyio.Extensions.Newtonsoft.Json/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.QueueStorage/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.QueueStorage/PackageReleaseNotes.txt index 137c823..2106262 100644 --- a/.nuget/Savvyio.Extensions.QueueStorage/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.QueueStorage/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.QueueStorage/README.md b/.nuget/Savvyio.Extensions.QueueStorage/README.md index 99783cf..ba7689c 100644 --- a/.nuget/Savvyio.Extensions.QueueStorage/README.md +++ b/.nuget/Savvyio.Extensions.QueueStorage/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.RabbitMQ/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.RabbitMQ/PackageReleaseNotes.txt new file mode 100644 index 0000000..41d4e3c --- /dev/null +++ b/.nuget/Savvyio.Extensions.RabbitMQ/PackageReleaseNotes.txt @@ -0,0 +1,14 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  +# New Features +- ADDED RabbitMqCommandQueue class in the Savvyio.Extensions.RabbitMQ.Commands namespace that provides a a default implementation of the RabbitMqMessage class for messages holding an ICommand implementation +- ADDED RabbitMqCommandQueueOptions class in the Savvyio.Extensions.RabbitMQ.Commands namespace that provides configuration options for RabbitMqCommandQueue +- ADDED RabbitMqEventBus class in the Savvyio.Extensions.RabbitMQ.EventDriven namespace that provides a default implementation of the RabbitMqMessage class for messages holding an IIntegrationEvent implementation +- ADDED RabbitMqEventBusOptions class in the Savvyio.Extensions.RabbitMQ.EventDriven namespace that provides configuration options for RabbitMqEventBus +- ADDED RabbitMqMessage class in the Savvyio.Extensions.RabbitMQ namespace that provides a base class for RabbitMQ message operations, including connection and channel management, marshalling, and resource disposal while ensuring thread-safe initialization of RabbitMQ connectivity +- ADDED RabbitMqMessageOptions class in the Savvyio.Extensions.RabbitMQ namespace that provides configuration options for RabbitMqMessage +  \ No newline at end of file diff --git a/.nuget/Savvyio.Extensions.RabbitMQ/README.md b/.nuget/Savvyio.Extensions.RabbitMQ/README.md new file mode 100644 index 0000000..767da05 --- /dev/null +++ b/.nuget/Savvyio.Extensions.RabbitMQ/README.md @@ -0,0 +1,45 @@ +# Savvyio.Extensions.RabbitMQ + +Extend the Savvy I/O core assemblies with support for RabbitMQ Work Queue and RabbitMQ Publish/Subscribe. + +## About + +An open-source project (MIT license) that provides a SOLID and clean .NET class library for writing DDD, CQRS and Event Sourcing applications. + +![Savvy I/O Flow](https://raw.githubusercontent.com/codebeltnet/savvyio/main/.assets/savvyio.png) + +It is, by heart, free, flexible and built to extend and boost your agile codebelt. + +## Related Packages + +* [Savvyio.App](https://www.nuget.org/packages/Savvyio.App/) 🏭 +* [Savvyio.Commands](https://www.nuget.org/packages/Savvyio.Commands/) 📦 +* [Savvyio.Commands.Messaging](https://www.nuget.org/packages/Savvyio.Commands.Messaging/) 📦 +* [Savvyio.Core](https://www.nuget.org/packages/Savvyio.Core/) 📦 +* [Savvyio.Domain](https://www.nuget.org/packages/Savvyio.Domain/) 📦 +* [Savvyio.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Domain.EventSourcing/) 📦 +* [Savvyio.EventDriven](https://www.nuget.org/packages/Savvyio.EventDriven/) 📦 +* [Savvyio.EventDriven.Messaging](https://www.nuget.org/packages/Savvyio.EventDriven.Messaging/) 📦 +* [Savvyio.Extensions.Dapper](https://www.nuget.org/packages/Savvyio.Extensions.Dapper/) 📦 +* [Savvyio.Extensions.DapperExtensions](https://www.nuget.org/packages/Savvyio.Extensions.DapperExtensions/) 📦 +* [Savvyio.Extensions.DependencyInjection](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection/) 📦 +* [Savvyio.Extensions.DependencyInjection.Dapper](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Dapper/) 📦 +* [Savvyio.Extensions.DependencyInjection.DapperExtensions](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.DapperExtensions/) 📦 +* [Savvyio.Extensions.DependencyInjection.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Domain/) 📦 +* [Savvyio.Extensions.DependencyInjection.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore/) 📦 +* [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 +* [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 +* [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 +* [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 +* [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 +* [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 +* [Savvyio.Extensions.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain/) 📦 +* [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 +* [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 +* [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 +* [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 +* [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 +* [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 +* [Savvyio.Queries](https://www.nuget.org/packages/Savvyio.Queries/) 📦 diff --git a/.nuget/Savvyio.Extensions.RabbitMQ/icon.png b/.nuget/Savvyio.Extensions.RabbitMQ/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..39600eaba64d060833613a50a133ad42af9222eb GIT binary patch literal 3693 zcmZXXc{CJk`^WDYgRy0QD36^;c6wxqv72mV-?D~e8C%8@X6!sF4I;!8LZm|38B3&$ zy)2`_Bt(|UNY;Ly_jk_k{NDHdcDq z7@Xnc?9ul4aN?MPO&r4jfbjog5D^Ph+DY(qxS>P1HOeO(?Gfq?&}g*0Uyy&8mq)O- zJSx<;a6{|NNydGofv!zt(fXs9aGQ_q{hgh$K4;lIMc~h^Zi%wDBN>{s8sxk6_nYjS zd7g0H^uO}V)ur1I=jn6SA%m)`%uOa&=gNq!)bZz3x~w}rchcV)rO@Fp1 z#m$FdaYy1RA+Dm?1J{SlhK>(&i|U0tFCDbTceW2}vwQj&Bz{~df~C-9I)V<5d3wWz zozxG4=2v;8N9k9qL7jb`o3zdT1tmE~JnT^r^i_Rn;Jc;1=jSy%eaf#B(j36}#*EJf z|4c(BRvGBWAmjcd6r@}}koPfI_LK+_6@xegevNW}MVAyp))#cY&8qhYMi%hVt{g&q zZrSR4e~Wpg?7-z5%}Z#gtE2sVFu@H{4g|IBH|x+bSn9484u_j*5hM)v@N|iMx1-M! zl0*Obck(E1N;KMZWV$$%6RIf;lq+iFg})tCgsf$pdhEvzjg&Owg!K_KE(<%Gy3`K5 zElk}RzK)b-+WJ?sLBluq;}XZ?2z;&Sh-S&5UEso-#o2TZD*z73`iuKheg_PoCSvkW zPuF2Wj?k*sTLPV*Z+%?Y7PWi>>-Rvys)gSDwXF-|h!L1}Z+p(XJf5~Oz7b`eBCDX6$&nq$u!*u6N63$#c^NHj}*RsSeNc4Ma z7GTWIZ74R;q`Q4v$bic&?csfEE2_Be6d37M^qU2jyp^gt_ua33vj^_4TWeGL1Q7Y7 z`pqxsDCB7S0b>ySwOzm{pJ(@srxOE#r^sR4tn^-u+m7L&lVm#ody?bPTyJGZq}y_# zvHb5fL3bIt;H&u!63P+r}hUb;qu7 z+YVHQsYg^46I*Z?G2ol<;p}__cUbA`UR$N(;<~{U<`}v$5+A)l*ICP^V6k+%gm(fT zPEYDrrly!RQ8J<{di;Jw)}>Qz5V!(T5Jh3w~enBhO>z zAI55=t)Hu^`UtYlI0-etAC%&-x*}Ws_GaIaj2M=)%P!hCDT}-#4NM}3s2g@e+=H7A zfxIuwUfSNh)KW`ZW2o>dXSi>Qml0Xy3T6NfLp~`kQDZiS(clpWynqC;y=zr8ZmQf>Ki|f-p-S`WY)kgOdWWnJd>_dRYwdiIerBH1(%gHhESId>LTa9*0OqUyGHpzG94S-qT4g zguUm$3nV1yV<_u4o@^Ck9XVb)cv1cO7H8M+PY;zvIvce-{$gy7UVXNF{905Lfi+}C zNWsF~;UdJv9l-NRh2vJmun1+%;Ic6ywN9-}T2u(X7TF|V;Ba3Qp#YOUl;D_uS&W4% zKrXU@K?&JQ;SHVpf+|n-qm9DhrZ;0uu&11I74cwF+&|x5i5bIxf7mShk z<*MeMZd(Wu&7APc(Dy8?0vTDN2r0b>*bWW^UQxb?g@>L^1#LH{6G-Zyp;67pE-U5N zMtPw#);;oc?XVOOC5TWvdEPy7VOr&34zF1x4@OGbQiJ=`)AA_o0a7!%Yw}XlzR%A0 zJv{`Tab!{Aih`bzkV>w_T=QlO>NtR0MVGwyLAU!dKC2xt$csKH*Vls)$miomfCgk< z*kjeo>k|~&31@D8NH* zNPc{jT1)C%;5M2pi4($%22jglxk`VU?5BZXn%++Ea}i5UL6{wxl)ucBbC(-dA66Yp{S*YojMN$eYC-RfsDTil@2YPs(7+QGd_ ze>Z~tWMll8<5{QA%4L@-I>x9*gU*ua`5UbX%UX@7r2f)ckKiWXV}OCo^kg`N&M&LQ zLBQNx^KSQUQ2T;^HF4mxAI#^Y{gl7d^tHUoLAQC*T~rNv`UPkyR?zx~QEXs=1eabh zYeC2M*8#oC!YC9Qhk>Sp*w zMm!rXZsbd;hYEUK&OM8Tup;zBh%YJkLh{~6yTb8A#0#pM$RRYd3f$$MvRe-Qez)pt z?7Ujc+_8mb^+Masd>OB_OwnGW39fi|nxL*3QPz^{@fO(i#F*N1Y);4zl?1(3ABMjB zuKoVT&kZG;>(R0TWU|BTrwWGNEOUhkS+S?BJI~w{;5M&A7cz}w%=re!yXuRhsGgrz zJkGYTVL$YZKlHUS64VKa6u>yQ_wy6vv-|7!OYiI+#jE!9GnYnm+%qv4so*mhyxkHl z!x8{h97ktjQ#G_TZOEeqbw#?Ra9Y5l@d(A}dauM$%{gO~*vhtm9wuuKqSCZNpa{G% zLiq$tA9}9y-#9EIM@Xwxw~yqII$furuA0Cj~KUp7CZ z00|f&-HojC+dVEserpAbcla5MnF;eI5dJ^Ufkbh7_h8&j-k08%>so9xxzQv}OIR;8 zm&MnH&1MfNj``QRMn3DZE3-xOXUfIgG&ZWM=VL>1LNhyF^~@)nMDo}SrkNBl#F$gF zHx`F>yXF&!3KL|ZwNP$XfQf!h{zHPf_qOe3)xHrI9HE?bQn)C|jb5>_*#v1hO1j(B z9m$;8)S$jVf5l~Mvts9sC^=xdUgy1K)Q;e3DC=DwOxJy=;zcXKVBCnDubUjYHcpmj zRcYnRNG-|NsWC!nCX5<_-;SSY%G_~cNmy5&Zi3)PU+qZc_$ixqbE?#aC}DDsTC2t> zLOF-FDT#7JX&$CmgUs1IZ7y?I2sh!8g4);9?c1>&)ErH>0OsA?k4@YZ?jfWg}-jt7@dN{T*NFretQudlEpMS<9vRX^0{-GSm;?6;$~c8SrX zY$eaOsQ2%U^PH58r)Y1=J0(ovB4IQ1$<2*gw0+yR!!+9Ku_ncZpG0;07jZvrO_$OR zMvhMPE=r2R@XeZYx+}X3`XY~AG{VC-Hl}$m)c*bS8sEkvLpr0rH0qKg`?1F!T8bEF zF1<7huY38lrKclD^u7rk(xmC6eR%M=v3Al1oj*L5%z;LYOkN!>h^Bmh)uXc>;1_-2 z)Y8u1NgM!71S)9!SiaRbxUPj>^^izYOY@m%C3QqCt(@v-Kd$@sW(NE6+$V`l0PuS@ zrL8{1d%vYP+jJXBkLCJhNdx-v0qNy(bVxlWLTWLY052t%B=G?JJvGJmmAg_N^z)@U zWcP_OVYc+LQ>AyJO8!DpT}QNN!tnr+f~a(<1$vrSl$8UCrZlA+h3zHOrA|j4SEVOAMkC{xzHIiAF$szr|_`m!op% zptu49G@<~1$i#t)^hr8Cl>5}x&0%~#teCw-EkAPksaneI<*|^CFYD&ruX4bL2%^%MF9!pK9c<8eHkLb#QOZ%%G1*%uWPkD2riCq zeHNS*8YRcEP}-ZvYFv6iVo-faHLUx$Ln7x1i59akgkD2`b!{2KG;>Zo2>NUNu%^eX zO~!RcQq@eLjo|bJc7^Fc*VLq?i|L zW6krTGz|4>^e9-x#Q1~k$0cil#)>UW2ps=AZ~XrO|L;2W?|uJ=i2e8FA-BN{w8qhf Swtezd1V}>*gIYcJg#Q5!QPfBP literal 0 HcmV?d00001 diff --git a/.nuget/Savvyio.Extensions.SimpleQueueService/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.SimpleQueueService/PackageReleaseNotes.txt index d1c716e..af7ebcd 100644 --- a/.nuget/Savvyio.Extensions.SimpleQueueService/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.SimpleQueueService/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.SimpleQueueService/README.md b/.nuget/Savvyio.Extensions.SimpleQueueService/README.md index f0f7d5c..8d5b943 100644 --- a/.nuget/Savvyio.Extensions.SimpleQueueService/README.md +++ b/.nuget/Savvyio.Extensions.SimpleQueueService/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Extensions.Text.Json/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.Text.Json/PackageReleaseNotes.txt index faa6d51..9a4d532 100644 --- a/.nuget/Savvyio.Extensions.Text.Json/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.Text.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Extensions.Text.Json/README.md b/.nuget/Savvyio.Extensions.Text.Json/README.md index f091efb..424cdd6 100644 --- a/.nuget/Savvyio.Extensions.Text.Json/README.md +++ b/.nuget/Savvyio.Extensions.Text.Json/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Messaging/PackageReleaseNotes.txt b/.nuget/Savvyio.Messaging/PackageReleaseNotes.txt index 47116e5..527af03 100644 --- a/.nuget/Savvyio.Messaging/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Messaging/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Messaging/README.md b/.nuget/Savvyio.Messaging/README.md index 9ea5354..e3eaab4 100644 --- a/.nuget/Savvyio.Messaging/README.md +++ b/.nuget/Savvyio.Messaging/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 diff --git a/.nuget/Savvyio.Queries/PackageReleaseNotes.txt b/.nuget/Savvyio.Queries/PackageReleaseNotes.txt index d918ce5..9032305 100644 --- a/.nuget/Savvyio.Queries/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Queries/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 4.1.0 +Availability: .NET 9 and .NET 8 +  +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) +  Version: 4.0.3 Availability: .NET 9 and .NET 8   diff --git a/.nuget/Savvyio.Queries/README.md b/.nuget/Savvyio.Queries/README.md index 5fe322c..3993fe3 100644 --- a/.nuget/Savvyio.Queries/README.md +++ b/.nuget/Savvyio.Queries/README.md @@ -30,6 +30,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦 * [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦 +* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦 * [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦 * [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦 * [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦 @@ -37,6 +38,7 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel * [Savvyio.Extensions.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain.EventSourcing/) 📦 * [Savvyio.Extensions.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.Newtonsoft.Json/) 📦 * [Savvyio.Extensions.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.QueueStorage/) 📦 +* [Savvyio.Extensions.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.RabbitMQ/) 📦 * [Savvyio.Extensions.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.SimpleQueueService/) 📦 * [Savvyio.Extensions.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.Text.Json/) 📦 * [Savvyio.Messaging](https://www.nuget.org/packages/Savvyio.Messaging/) 📦 From 1ace24b94e10fa71dfc2803bb704c5a784eb7ca5 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:42:36 +0200 Subject: [PATCH 07/16] :sparkles: support for RabbitMQ with Microsoft Dependency Injection --- Savvyio.sln | 21 +++++ .../Commands/RabbitMqCommandQueue.cs | 32 ++++++++ .../Commands/RabbitMqCommandQueueOptions.cs | 14 ++++ .../EventDriven/RabbitMqEventBus.cs | 33 ++++++++ .../EventDriven/RabbitMqEventBusOptions.cs | 14 ++++ ...nsions.DependencyInjection.RabbitMQ.csproj | 13 +++ .../ServiceCollectionExtensions.cs | 79 +++++++++++++++++++ 7 files changed, 206 insertions(+) create mode 100644 src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Commands/RabbitMqCommandQueue.cs create mode 100644 src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs create mode 100644 src/Savvyio.Extensions.DependencyInjection.RabbitMQ/EventDriven/RabbitMqEventBus.cs create mode 100644 src/Savvyio.Extensions.DependencyInjection.RabbitMQ/EventDriven/RabbitMqEventBusOptions.cs create mode 100644 src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Savvyio.Extensions.DependencyInjection.RabbitMQ.csproj create mode 100644 src/Savvyio.Extensions.DependencyInjection.RabbitMQ/ServiceCollectionExtensions.cs diff --git a/Savvyio.sln b/Savvyio.sln index fb3589a..e47ffad 100644 --- a/Savvyio.sln +++ b/Savvyio.sln @@ -123,6 +123,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Savvyio.Extensions.RabbitMQ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Savvyio.Extensions.RabbitMQ.FunctionalTests", "test\Savvyio.Extensions.RabbitMQ.FunctionalTests\Savvyio.Extensions.RabbitMQ.FunctionalTests.csproj", "{C15021DF-E983-4B40-8F65-16A8966429AF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Savvyio.Extensions.DependencyInjection.RabbitMQ", "src\Savvyio.Extensions.DependencyInjection.RabbitMQ\Savvyio.Extensions.DependencyInjection.RabbitMQ.csproj", "{03FA8A80-ADD3-41CC-B55F-E435120D6DA9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests", "test\Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests\Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests.csproj", "{5424475B-B2EB-4CF2-B7D5-D23CDE9A8D59}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Savvyio.Extensions.RabbitMQ.Tests", "test\Savvyio.Extensions.RabbitMQ.Tests\Savvyio.Extensions.RabbitMQ.Tests.csproj", "{0AE5B8A9-228D-4A7E-A931-FDF84A4217D3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -361,6 +367,18 @@ Global {C15021DF-E983-4B40-8F65-16A8966429AF}.Debug|Any CPU.Build.0 = Debug|Any CPU {C15021DF-E983-4B40-8F65-16A8966429AF}.Release|Any CPU.ActiveCfg = Release|Any CPU {C15021DF-E983-4B40-8F65-16A8966429AF}.Release|Any CPU.Build.0 = Release|Any CPU + {03FA8A80-ADD3-41CC-B55F-E435120D6DA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {03FA8A80-ADD3-41CC-B55F-E435120D6DA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {03FA8A80-ADD3-41CC-B55F-E435120D6DA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {03FA8A80-ADD3-41CC-B55F-E435120D6DA9}.Release|Any CPU.Build.0 = Release|Any CPU + {5424475B-B2EB-4CF2-B7D5-D23CDE9A8D59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5424475B-B2EB-4CF2-B7D5-D23CDE9A8D59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5424475B-B2EB-4CF2-B7D5-D23CDE9A8D59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5424475B-B2EB-4CF2-B7D5-D23CDE9A8D59}.Release|Any CPU.Build.0 = Release|Any CPU + {0AE5B8A9-228D-4A7E-A931-FDF84A4217D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0AE5B8A9-228D-4A7E-A931-FDF84A4217D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0AE5B8A9-228D-4A7E-A931-FDF84A4217D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0AE5B8A9-228D-4A7E-A931-FDF84A4217D3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -424,6 +442,9 @@ Global {36520BC5-4343-4CF3-A8AE-B7A04B91DDB2} = {0E75F0C5-DBEB-4B6D-AC52-98656CA79A7D} {0AB0316F-76C4-413F-8C96-DB3489E318E6} = {0E75F0C5-DBEB-4B6D-AC52-98656CA79A7D} {C15021DF-E983-4B40-8F65-16A8966429AF} = {407762FB-26D8-435F-AE16-C76791EC9FEC} + {03FA8A80-ADD3-41CC-B55F-E435120D6DA9} = {0E75F0C5-DBEB-4B6D-AC52-98656CA79A7D} + {5424475B-B2EB-4CF2-B7D5-D23CDE9A8D59} = {407762FB-26D8-435F-AE16-C76791EC9FEC} + {0AE5B8A9-228D-4A7E-A931-FDF84A4217D3} = {407762FB-26D8-435F-AE16-C76791EC9FEC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D8DDAD51-08E6-42B5-970B-2DC88D44297B} diff --git a/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Commands/RabbitMqCommandQueue.cs b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Commands/RabbitMqCommandQueue.cs new file mode 100644 index 0000000..5dc12e5 --- /dev/null +++ b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Commands/RabbitMqCommandQueue.cs @@ -0,0 +1,32 @@ +using System; +using Savvyio.Commands; +using Savvyio.Extensions.DependencyInjection.Messaging; +using Savvyio.Extensions.RabbitMQ; +using Savvyio.Extensions.RabbitMQ.Commands; + +namespace Savvyio.Extensions.DependencyInjection.RabbitMQ.Commands +{ + /// + /// Provides a default implementation of the class for messages holding an implementation. + /// + /// + /// + public class RabbitMqCommandQueue : RabbitMqCommandQueue, IPointToPointChannel + { + /// + /// Initializes a new instance of the class. + /// + /// The marshaller used for serializing and deserializing messages. + /// The options used to configure the RabbitMQ command queue. + /// + /// cannot be null -or- + /// cannot be null. + /// + /// + /// are not in a valid state. + /// + public RabbitMqCommandQueue(IMarshaller marshaller, RabbitMqCommandQueueOptions options) : base(marshaller, options) + { + } + } +} diff --git a/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs new file mode 100644 index 0000000..0c7acf7 --- /dev/null +++ b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs @@ -0,0 +1,14 @@ +using Cuemon.Extensions.DependencyInjection; +using Savvyio.Extensions.RabbitMQ.Commands; + +namespace Savvyio.Extensions.DependencyInjection.RabbitMQ.Commands +{ + /// + /// Configuration options for . + /// + /// + /// + public class RabbitMqCommandQueueOptions : RabbitMqCommandQueueOptions, IDependencyInjectionMarker + { + } +} diff --git a/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/EventDriven/RabbitMqEventBus.cs b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/EventDriven/RabbitMqEventBus.cs new file mode 100644 index 0000000..8666044 --- /dev/null +++ b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/EventDriven/RabbitMqEventBus.cs @@ -0,0 +1,33 @@ +using Savvyio.Extensions.RabbitMQ.EventDriven; +using System; +using Savvyio.EventDriven; +using Savvyio.Extensions.DependencyInjection.Messaging; +using Savvyio.Extensions.RabbitMQ; + +namespace Savvyio.Extensions.DependencyInjection.RabbitMQ.EventDriven +{ + /// + /// Provides a default implementation of the class for messages holding an implementation. + /// + /// + /// + public class RabbitMqEventBus : RabbitMqEventBus, IPublishSubscribeChannel + { + + /// + /// Initializes a new instance of the class. + /// + /// The marshaller used for serializing and deserializing messages. + /// The options used to configure the RabbitMQ event bus. + /// + /// cannot be null -or- + /// cannot be null. + /// + /// + /// are not in a valid state. + /// + public RabbitMqEventBus(IMarshaller marshaller, RabbitMqEventBusOptions options) : base(marshaller, options) + { + } + } +} diff --git a/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/EventDriven/RabbitMqEventBusOptions.cs b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/EventDriven/RabbitMqEventBusOptions.cs new file mode 100644 index 0000000..45ee961 --- /dev/null +++ b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/EventDriven/RabbitMqEventBusOptions.cs @@ -0,0 +1,14 @@ +using Cuemon.Extensions.DependencyInjection; +using Savvyio.Extensions.RabbitMQ.EventDriven; + +namespace Savvyio.Extensions.DependencyInjection.RabbitMQ.EventDriven +{ + /// + /// Configuration options for . + /// + /// + /// + public class RabbitMqEventBusOptions : RabbitMqEventBusOptions, IDependencyInjectionMarker + { + } +} diff --git a/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Savvyio.Extensions.DependencyInjection.RabbitMQ.csproj b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Savvyio.Extensions.DependencyInjection.RabbitMQ.csproj new file mode 100644 index 0000000..23f83cb --- /dev/null +++ b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/Savvyio.Extensions.DependencyInjection.RabbitMQ.csproj @@ -0,0 +1,13 @@ + + + + Extend the Savvy I/O support for Microsoft Dependency Injection with RabbitMQ Worker Queue and Publish/Subscribe implementations. + rabbitmq worker queue publish subscribe bus di depedency-injection + + + + + + + + diff --git a/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/ServiceCollectionExtensions.cs b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..0061229 --- /dev/null +++ b/src/Savvyio.Extensions.DependencyInjection.RabbitMQ/ServiceCollectionExtensions.cs @@ -0,0 +1,79 @@ +using Cuemon.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; +using Savvyio.Extensions.DependencyInjection.Messaging; +using Savvyio.Extensions.DependencyInjection.RabbitMQ.Commands; +using Savvyio.Extensions.DependencyInjection.RabbitMQ.EventDriven; +using System; +using Savvyio.Commands; +using Savvyio.EventDriven; +using Savvyio.Extensions.RabbitMQ.Commands; +using Savvyio.Extensions.RabbitMQ.EventDriven; + +namespace Savvyio.Extensions.DependencyInjection.RabbitMQ +{ + /// + /// Extension methods for the interface. + /// + public static class ServiceCollectionExtensions + { + /// + /// Adds an implementation to the specified . + /// + /// The to extend. + /// The that needs to be configured. + /// The which may be configured. + /// A reference to so that additional calls can be chained. + /// The implementation will be type forwarded accordingly. + public static IServiceCollection AddRabbitMqCommandQueue(this IServiceCollection services, Action rabbitMqSetup, Action serviceSetup = null) + { + return services + .AddMessageQueue(serviceSetup ?? (o => o.Lifetime = ServiceLifetime.Singleton)) + .AddConfiguredOptions(rabbitMqSetup); + } + + /// + /// Adds an implementation to the specified . + /// + /// The to extend. + /// The that needs to be configured. + /// The which may be configured. + /// A reference to so that additional calls can be chained. + /// The implementation will be type forwarded accordingly. + public static IServiceCollection AddRabbitMqCommandQueue(this IServiceCollection services, Action> rabbitMqSetup, Action serviceSetup = null) + { + return services + .AddMessageQueue, ICommand>(serviceSetup ?? (o => o.Lifetime = ServiceLifetime.Singleton)) + .AddConfiguredOptions(rabbitMqSetup); + } + + /// + /// Adds an implementation to the specified . + /// + /// The to extend. + /// The that needs to be configured. + /// The which may be configured. + /// A reference to so that additional calls can be chained. + /// The implementation will be type forwarded accordingly. + public static IServiceCollection AddRabbitMqEventBus(this IServiceCollection services, Action rabbitMqSetup, Action serviceSetup = null) + { + return services + .AddMessageBus(serviceSetup ?? (o => o.Lifetime = ServiceLifetime.Singleton)) + .AddConfiguredOptions(rabbitMqSetup); + } + + /// + /// Adds an implementation to the specified . + /// + /// The to extend. + /// The that needs to be configured. + /// The which may be configured. + /// A reference to so that additional calls can be chained. + /// The implementation will be type forwarded accordingly. + public static IServiceCollection AddRabbitMqEventBus(this IServiceCollection services, Action> rabbitMqSetup, Action serviceSetup = null) + { + return services + .AddMessageBus, IIntegrationEvent>(serviceSetup ?? (o => o.Lifetime = ServiceLifetime.Singleton)) + .AddConfiguredOptions(rabbitMqSetup); + } + } +} From 9cdaf2fa4032d5062e5248b8f3b0c0a3a2314dbb Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:43:14 +0200 Subject: [PATCH 08/16] :sparkles: includes RabbitMQ as part of app package --- src/Savvyio.App/Savvyio.App.csproj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Savvyio.App/Savvyio.App.csproj b/src/Savvyio.App/Savvyio.App.csproj index 9853983..5e2aed4 100644 --- a/src/Savvyio.App/Savvyio.App.csproj +++ b/src/Savvyio.App/Savvyio.App.csproj @@ -3,8 +3,8 @@ false false - Provides a complete and convenient set of API additions for building a DDD, CQRS and Event Sourcing enabled .NET application using Microsoft Dependency Injection, Microsoft Entity Framework Core, Dapper, AWS SNS/SQS and Azure Queue Storage/Azure Event Grid. - ddd domain-driven-design cqrs command-query-responsibility-segregation es event-sourcing datastore data-store datasource data-source dataaccessobject data-access-object repository de domain-event ie integration-event valueobject value-object entity aggregate aggregate-root eventdriven event-driven ef-core ef entity-framework entity-framework-core di dependency-injection aws amazon awssqs awssns simplequeueservice sqs simplenotificationservice sns queue bus json converters converter azure storage event-grid + Provides a complete and convenient set of API additions for building a DDD, CQRS and Event Sourcing enabled .NET application using Microsoft Dependency Injection, Microsoft Entity Framework Core, Dapper, AWS SNS/SQS, Azure Queue Storage/Azure Event Grid and RabbitMQ Worker Queue/Publish-Subscribe. + ddd domain-driven-design cqrs command-query-responsibility-segregation es event-sourcing datastore data-store datasource data-source dataaccessobject data-access-object repository de domain-event ie integration-event valueobject value-object entity aggregate aggregate-root eventdriven event-driven ef-core ef entity-framework entity-framework-core di dependency-injection aws amazon awssqs awssns simplequeueservice sqs simplenotificationservice sns queue bus json converters converter azure storage event-grid rabbitmq worker worker-queue publish subscribe Savvyio.App NU5128 @@ -24,6 +24,7 @@ + @@ -31,6 +32,7 @@ + From 00690af58fc5160a123fa3bdb754388ff2d4d089 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:43:32 +0200 Subject: [PATCH 09/16] :white_check_mark: complementary unit tests --- .../Assets/BusMarker.cs | 7 + .../Assets/QueueMarker.cs | 7 + ....DependencyInjection.RabbitMQ.Tests.csproj | 17 ++ .../ServiceCollectionExtensionsTest.cs | 151 ++++++++++++++++++ .../RabbitMqCommandQueueOptionsTest.cs | 41 +++++ .../RabbitMqEventBusOptionsTest.cs | 41 +++++ .../RabbitMqMessageOptionsTest.cs | 40 +++++ .../Savvyio.Extensions.RabbitMQ.Tests.csproj | 17 ++ 8 files changed, 321 insertions(+) create mode 100644 test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Assets/BusMarker.cs create mode 100644 test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Assets/QueueMarker.cs create mode 100644 test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests.csproj create mode 100644 test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/ServiceCollectionExtensionsTest.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.Tests/Commands/RabbitMqCommandQueueOptionsTest.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.Tests/EventDriven/RabbitMqEventBusOptionsTest.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.Tests/RabbitMqMessageOptionsTest.cs create mode 100644 test/Savvyio.Extensions.RabbitMQ.Tests/Savvyio.Extensions.RabbitMQ.Tests.csproj diff --git a/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Assets/BusMarker.cs b/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Assets/BusMarker.cs new file mode 100644 index 0000000..dbbc5af --- /dev/null +++ b/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Assets/BusMarker.cs @@ -0,0 +1,7 @@ +namespace Savvyio.Extensions.DependencyInjection.RabbitMQ.Assets +{ + public struct BusMarker + { + + } +} \ No newline at end of file diff --git a/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Assets/QueueMarker.cs b/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Assets/QueueMarker.cs new file mode 100644 index 0000000..06d3689 --- /dev/null +++ b/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Assets/QueueMarker.cs @@ -0,0 +1,7 @@ +namespace Savvyio.Extensions.DependencyInjection.RabbitMQ.Assets +{ + public struct QueueMarker + { + + } +} \ No newline at end of file diff --git a/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests.csproj b/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests.csproj new file mode 100644 index 0000000..62b09b6 --- /dev/null +++ b/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests.csproj @@ -0,0 +1,17 @@ + + + + Savvyio.Extensions.DependencyInjection.RabbitMQ + + + + + + + + + + + + + diff --git a/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/ServiceCollectionExtensionsTest.cs b/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/ServiceCollectionExtensionsTest.cs new file mode 100644 index 0000000..46e5685 --- /dev/null +++ b/test/Savvyio.Extensions.DependencyInjection.RabbitMQ.Tests/ServiceCollectionExtensionsTest.cs @@ -0,0 +1,151 @@ +using System; +using Codebelt.Extensions.Xunit; +using Microsoft.Extensions.DependencyInjection; +using Savvyio.Commands; +using Savvyio.EventDriven; +using Savvyio.Extensions.DependencyInjection.Messaging; +using Savvyio.Extensions.DependencyInjection.RabbitMQ.Assets; +using Savvyio.Extensions.DependencyInjection.RabbitMQ.Commands; +using Savvyio.Extensions.DependencyInjection.RabbitMQ.EventDriven; +using Savvyio.Extensions.Newtonsoft.Json; +using Savvyio.Extensions.RabbitMQ.Commands; +using Savvyio.Extensions.RabbitMQ.EventDriven; +using Savvyio.Extensions.Text.Json; +using Savvyio.Messaging; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace Savvyio.Extensions.DependencyInjection.RabbitMQ +{ + public class ServiceCollectionExtensionsTest : Test + { + public ServiceCollectionExtensionsTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public void AddRabbitMqCommandQueue_ShouldAddDefaultImplementation() + { + Action rabbitMqSetup = o => + { + o.QueueName = "urn:queue"; + }; + + var sut1 = new ServiceCollection(); + sut1.AddMarshaller(); + sut1.AddRabbitMqCommandQueue(rabbitMqSetup); + var sut2 = sut1.BuildServiceProvider(); + + Assert.IsType(sut2.GetRequiredService>()); + Assert.IsType(sut2.GetRequiredService>()); + Assert.IsType(sut2.GetRequiredService>()); + + var opt1 = new RabbitMqCommandQueueOptions(); + var opt2 = new RabbitMqCommandQueueOptions(); + var opt3 = new RabbitMqCommandQueueOptions(); + + rabbitMqSetup.Invoke(opt1); + sut2.GetRequiredService>().Invoke(opt2); + + Assert.Equivalent(rabbitMqSetup, sut2.GetRequiredService>()); + Assert.Equivalent(opt1, opt2); + + Assert.Throws(() => Assert.Equivalent(opt1, opt3)); + Assert.Throws(() => Assert.Equivalent(opt2, opt3)); + } + + [Fact] + public void AddRabbitMqCommandQueue_ShouldAddDefaultImplementationWithMarker() + { + Action> rabbitMqSetup = o => + { + o.QueueName = "urn:queue"; + }; + + var sut1 = new ServiceCollection(); + sut1.AddMarshaller(); + sut1.AddRabbitMqCommandQueue(rabbitMqSetup); + var sut2 = sut1.BuildServiceProvider(); + + Assert.IsType>(sut2.GetRequiredService>()); + Assert.IsType>(sut2.GetRequiredService>()); + Assert.IsType>(sut2.GetRequiredService>()); + + var opt1 = new RabbitMqCommandQueueOptions(); + var opt2 = new RabbitMqCommandQueueOptions(); + var opt3 = new RabbitMqCommandQueueOptions(); + + rabbitMqSetup.Invoke(opt1); + sut2.GetRequiredService>>().Invoke(opt2); + + Assert.Equivalent(rabbitMqSetup, sut2.GetRequiredService>>()); + Assert.Equivalent(opt1, opt2); + + Assert.Throws(() => Assert.Equivalent(opt1, opt3)); + Assert.Throws(() => Assert.Equivalent(opt2, opt3)); + } + + [Fact] + public void AddRabbitMqEventBus_ShouldAddDefaultImplementation() + { + Action rabbitMqSetup = o => + { + o.ExchangeName = "urn:bus"; + }; + + var sut1 = new ServiceCollection(); + sut1.AddMarshaller(); + sut1.AddRabbitMqEventBus(rabbitMqSetup); + var sut2 = sut1.BuildServiceProvider(); + + Assert.IsType(sut2.GetRequiredService>()); + Assert.IsType(sut2.GetRequiredService>()); + Assert.IsType(sut2.GetRequiredService>()); + + var opt1 = new RabbitMqEventBusOptions(); + var opt2 = new RabbitMqEventBusOptions(); + var opt3 = new RabbitMqEventBusOptions(); + + rabbitMqSetup.Invoke(opt1); + sut2.GetRequiredService>().Invoke(opt2); + + Assert.Equivalent(rabbitMqSetup, sut2.GetRequiredService>()); + Assert.Equivalent(opt1, opt2); + + Assert.Throws(() => Assert.Equivalent(opt1, opt3)); + Assert.Throws(() => Assert.Equivalent(opt2, opt3)); + } + + [Fact] + public void AddRabbitMqEventBus_ShouldAddDefaultImplementationWithMarker() + { + Action> rabbitMqSetup = o => + { + o.ExchangeName = "urn:bus"; + }; + + var sut1 = new ServiceCollection(); + sut1.AddMarshaller(); + sut1.AddRabbitMqEventBus(rabbitMqSetup); + var sut2 = sut1.BuildServiceProvider(); + + Assert.IsType>(sut2.GetRequiredService>()); + Assert.IsType>(sut2.GetRequiredService>()); + Assert.IsType>(sut2.GetRequiredService>()); + + var opt1 = new RabbitMqEventBusOptions(); + var opt2 = new RabbitMqEventBusOptions(); + var opt3 = new RabbitMqEventBusOptions(); + + rabbitMqSetup.Invoke(opt1); + sut2.GetRequiredService>>().Invoke(opt2); + + Assert.Equivalent(rabbitMqSetup, sut2.GetRequiredService>>()); + Assert.Equivalent(opt1, opt2); + + Assert.Throws(() => Assert.Equivalent(opt1, opt3)); + Assert.Throws(() => Assert.Equivalent(opt2, opt3)); + } + } +} diff --git a/test/Savvyio.Extensions.RabbitMQ.Tests/Commands/RabbitMqCommandQueueOptionsTest.cs b/test/Savvyio.Extensions.RabbitMQ.Tests/Commands/RabbitMqCommandQueueOptionsTest.cs new file mode 100644 index 0000000..4f9c618 --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.Tests/Commands/RabbitMqCommandQueueOptionsTest.cs @@ -0,0 +1,41 @@ +using System; +using Xunit; + +namespace Savvyio.Extensions.RabbitMQ.Commands +{ + public class RabbitMqCommandQueueOptionsTest + { + [Fact] + public void Constructor_Should_Set_Defaults() + { + var options = new RabbitMqCommandQueueOptions(); + + Assert.Null(options.QueueName); + Assert.False(options.AutoAcknowledge); + Assert.NotNull(options.AmqpUrl); // Inherited from RabbitMqMessageOptions + } + + [Fact] + public void ValidateOptions_Should_Throw_When_QueueName_Is_Null_Or_Empty() + { + var options = new RabbitMqCommandQueueOptions(); + + Assert.Throws(() => options.ValidateOptions()); + + options.QueueName = ""; + Assert.Throws(() => options.ValidateOptions()); + } + + [Fact] + public void ValidateOptions_Should_Not_Throw_When_QueueName_Is_Set() + { + var options = new RabbitMqCommandQueueOptions + { + QueueName = "test-queue" + }; + + var exception = Record.Exception(() => options.ValidateOptions()); + Assert.Null(exception); + } + } +} diff --git a/test/Savvyio.Extensions.RabbitMQ.Tests/EventDriven/RabbitMqEventBusOptionsTest.cs b/test/Savvyio.Extensions.RabbitMQ.Tests/EventDriven/RabbitMqEventBusOptionsTest.cs new file mode 100644 index 0000000..a2015d8 --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.Tests/EventDriven/RabbitMqEventBusOptionsTest.cs @@ -0,0 +1,41 @@ +using System; +using Xunit; + +namespace Savvyio.Extensions.RabbitMQ.EventDriven +{ + public class RabbitMqEventBusOptionsTest + { + [Fact] + public void Constructor_Should_Set_Defaults() + { + var options = new RabbitMqEventBusOptions(); + + Assert.Null(options.ExchangeName); + Assert.NotNull(options.AmqpUrl); // Inherited from RabbitMqMessageOptions + Assert.Equal(new Uri("amqp://localhost:5672"), options.AmqpUrl); + } + + [Fact] + public void ValidateOptions_Should_Throw_When_ExchangeName_Is_Null_Or_Empty() + { + var options = new RabbitMqEventBusOptions(); + + Assert.Throws(() => options.ValidateOptions()); + + options.ExchangeName = ""; + Assert.Throws(() => options.ValidateOptions()); + } + + [Fact] + public void ValidateOptions_Should_Not_Throw_When_ExchangeName_Is_Set() + { + var options = new RabbitMqEventBusOptions + { + ExchangeName = "test-exchange" + }; + + var exception = Record.Exception(() => options.ValidateOptions()); + Assert.Null(exception); + } + } +} \ No newline at end of file diff --git a/test/Savvyio.Extensions.RabbitMQ.Tests/RabbitMqMessageOptionsTest.cs b/test/Savvyio.Extensions.RabbitMQ.Tests/RabbitMqMessageOptionsTest.cs new file mode 100644 index 0000000..6fd4400 --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.Tests/RabbitMqMessageOptionsTest.cs @@ -0,0 +1,40 @@ +using System; +using Xunit; + +namespace Savvyio.Extensions.RabbitMQ +{ + public class RabbitMqMessageOptionsTest + { + [Fact] + public void Constructor_Should_Set_Default_AmqpUrl() + { + var options = new RabbitMqMessageOptions(); + + Assert.NotNull(options.AmqpUrl); + Assert.Equal(new Uri("amqp://localhost:5672"), options.AmqpUrl); + } + + [Fact] + public void ValidateOptions_Should_Throw_When_AmqpUrl_Is_Null() + { + var options = new RabbitMqMessageOptions + { + AmqpUrl = null + }; + + Assert.Throws(() => options.ValidateOptions()); + } + + [Fact] + public void ValidateOptions_Should_Not_Throw_When_AmqpUrl_Is_Set() + { + var options = new RabbitMqMessageOptions + { + AmqpUrl = new Uri("amqp://localhost:5672") + }; + + var exception = Record.Exception(() => options.ValidateOptions()); + Assert.Null(exception); + } + } +} diff --git a/test/Savvyio.Extensions.RabbitMQ.Tests/Savvyio.Extensions.RabbitMQ.Tests.csproj b/test/Savvyio.Extensions.RabbitMQ.Tests/Savvyio.Extensions.RabbitMQ.Tests.csproj new file mode 100644 index 0000000..4f22257 --- /dev/null +++ b/test/Savvyio.Extensions.RabbitMQ.Tests/Savvyio.Extensions.RabbitMQ.Tests.csproj @@ -0,0 +1,17 @@ + + + + Savvyio.Extensions.RabbitMQ + + + + + + + + + + + + + From a567b79155b4836f22ffa5e0854006b5ad4642f1 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:44:06 +0200 Subject: [PATCH 10/16] :recycle: include more options to configure --- .../Commands/RabbitMqCommandQueue.cs | 10 +++-- .../Commands/RabbitMqCommandQueueOptions.cs | 39 +++++++++++++++++++ .../EventDriven/RabbitMqEventBus.cs | 6 ++- .../RabbitMqMessageOptions.cs | 16 +++++++- .../Savvyio.Extensions.RabbitMQ.csproj | 4 +- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs index daf5db5..966a0e7 100644 --- a/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs +++ b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs @@ -16,8 +16,10 @@ namespace Savvyio.Extensions.RabbitMQ.Commands { /// - /// Represents a RabbitMQ-based implementation of a point-to-point command queue. + /// Provides a default implementation of the class for messages holding an implementation. /// + /// + /// public class RabbitMqCommandQueue : RabbitMqMessage, IPointToPointChannel { private readonly RabbitMqCommandQueueOptions _options; @@ -52,13 +54,13 @@ public async Task SendAsync(IEnumerable> messages, Action() { { MessageType, message.GetType().ToFullNameIncludingAssemblyName() } @@ -80,7 +82,7 @@ public async IAsyncEnumerable> ReceiveAsync(Action>(); var consumer = new AsyncEventingBasicConsumer(RabbitMqChannel); diff --git a/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs index 2edceed..ca35fbe 100644 --- a/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs +++ b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueueOptions.cs @@ -27,6 +27,18 @@ public class RabbitMqCommandQueueOptions : RabbitMqMessageOptions /// /// false /// + /// + /// + /// false + /// + /// + /// + /// false + /// + /// + /// + /// false + /// /// /// public RabbitMqCommandQueueOptions() @@ -49,6 +61,33 @@ public RabbitMqCommandQueueOptions() /// public bool AutoAcknowledge { get; set; } + /// + /// Gets or sets a value indicating whether the queue should be durable. + /// + /// true if the queue should survive broker restarts; otherwise, false. + /// + /// Durable queues remain declared after a RabbitMQ broker restart, but messages in non-persistent queues will be lost. + /// + public bool Durable { get; set; } + + /// + /// Gets or sets a value indicating whether the queue should be exclusive. + /// + /// true if the queue is used by only one connection and deleted when that connection closes; otherwise, false. + /// + /// Exclusive queues are only accessible by the connection that declares them and are deleted when that connection closes. + /// + public bool Exclusive { get; set; } + + /// + /// Gets or sets a value indicating whether the queue should be automatically deleted when no longer in use. + /// + /// true if the queue is automatically deleted when the last consumer unsubscribes; otherwise, false. + /// + /// Auto-delete queues are deleted when the last consumer unsubscribes. If there are no consumers, the queue is not deleted. + /// + public bool AutoDelete { get; set; } + /// /// Determines whether the public read-write properties of this instance are in a valid state. /// diff --git a/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBus.cs b/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBus.cs index 4eb22b5..f8d374a 100644 --- a/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBus.cs +++ b/src/Savvyio.Extensions.RabbitMQ/EventDriven/RabbitMqEventBus.cs @@ -16,11 +16,12 @@ namespace Savvyio.Extensions.RabbitMQ.EventDriven { /// - /// Represents a RabbitMQ-based implementation of a publish-subscribe event bus for integration events. + /// Provides a default implementation of the class for messages holding an implementation. /// + /// + /// public class RabbitMqEventBus : RabbitMqMessage, IPublishSubscribeChannel { - private readonly ConnectionFactory _factory; private readonly RabbitMqEventBusOptions _options; /// @@ -57,6 +58,7 @@ public async Task PublishAsync(IMessage message, Action() { { MessageType, message.GetType().ToFullNameIncludingAssemblyName() } diff --git a/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessageOptions.cs b/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessageOptions.cs index 19ff9f6..84f6b76 100644 --- a/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessageOptions.cs +++ b/src/Savvyio.Extensions.RabbitMQ/RabbitMqMessageOptions.cs @@ -14,7 +14,7 @@ public class RabbitMqMessageOptions : IValidatableParameterObject /// Initializes a new instance of the class with default values. /// /// - /// The following table shows the initial property values for an instance of . + /// The following table shows the initial property values for an instance of . /// /// /// Property @@ -24,6 +24,10 @@ public class RabbitMqMessageOptions : IValidatableParameterObject /// /// new Uri("amqp://localhost:5672") /// + /// + /// + /// false + /// /// /// public RabbitMqMessageOptions() @@ -39,6 +43,16 @@ public RabbitMqMessageOptions() /// public Uri AmqpUrl { get; set; } + /// + /// Gets or sets a value indicating whether messages should be published as persistent. + /// + /// true if messages are marked as persistent and survive broker restarts; otherwise, false. + /// + /// When set to true, messages are stored to disk by RabbitMQ, ensuring delivery even if the broker restarts. + /// This corresponds to setting the delivery mode to persistent (2) in RabbitMQ. + /// + public bool Persistent { get; set; } + /// /// Determines whether the public read-write properties of this instance are in a valid state. /// diff --git a/src/Savvyio.Extensions.RabbitMQ/Savvyio.Extensions.RabbitMQ.csproj b/src/Savvyio.Extensions.RabbitMQ/Savvyio.Extensions.RabbitMQ.csproj index 62f517e..5299f41 100644 --- a/src/Savvyio.Extensions.RabbitMQ/Savvyio.Extensions.RabbitMQ.csproj +++ b/src/Savvyio.Extensions.RabbitMQ/Savvyio.Extensions.RabbitMQ.csproj @@ -1,8 +1,8 @@  - Extend the Savvy I/O core assemblies with support for RabbitMQ Work Queue and RabbitMQ Publish-Subscribe. - azure queue storage event-grid bus + Extend the Savvy I/O core assemblies with support for RabbitMQ Work Queue and RabbitMQ Publish/Subscribe. + rabbitmq worker queue publish subscribe bus From 113ac2d931dbd41550d3b70dcb1de57bb9bb6e99 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:44:15 +0200 Subject: [PATCH 11/16] :speech_balloon: updated community health pages --- CHANGELOG.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cb1c95..331e43c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,31 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), For more details, please refer to `PackageReleaseNotes.txt` on a per assembly basis in the `.nuget` folder. +## [4.1.0] - 2025-06-09 + +This is a feature release that offers support for RabbitMQ as a message broker in the context of RabbitMQ Worker Queue (Command) and RabbitMQ Publish/Subscribe (Integration Event). + +Also includes a service update that primarily focuses on bumping package dependencies. + +### Added + +#### Savvyio.Extensions.DependencyInjection.RabbitMQ + +- RabbitMqCommandQueue{TMarker} class in the Savvyio.Extensions.DependencyInjection.RabbitMQ.Commands namespace that provides default implementation of the RabbitMqMessage class for messages holding an ICommand implementation +- RabbitMqCommandQueueOptions{TMarker} class in the Savvyio.Extensions.DependencyInjection.RabbitMQ.Commands namespace that provides configuration options for RabbitMqCommandQueue{TMarker} +- RabbitMqEventBus{TMarker} class in the Savvyio.Extensions.DependencyInjection.RabbitMQ.EventDriven namespace that provides a default implementation of the RabbitMqMessage class for messages holding an IIntegrationEvent implementation +- RabbitMqEventBusOptions{TMarker} class in the Savvyio.Extensions.DependencyInjection.RabbitMQ.EventDriven namespace that provides configuration options for RabbitMqEventBus{TMarker} +- ServiceCollectionExtensions class in the Savvyio.Extensions.DependencyInjection.RabbitMQ namespace that consist of extension methods for the IServiceCollection interface: AddRabbitMqCommandQueue, AddRabbitMqEventBus + +#### Savvyio.Extensions.RabbitMQ + +- RabbitMqCommandQueue class in the Savvyio.Extensions.RabbitMQ.Commands namespace that provides a default implementation of the RabbitMqMessage class for messages holding an ICommand implementation +- RabbitMqCommandQueueOptions class in the Savvyio.Extensions.RabbitMQ.Commands namespace that provides configuration options for RabbitMqCommandQueue +- RabbitMqEventBus class in the Savvyio.Extensions.RabbitMQ.EventDriven namespace that provides a default implementation of the RabbitMqMessage class for messages holding an IIntegrationEvent implementation +- RabbitMqEventBusOptions class in the Savvyio.Extensions.RabbitMQ.EventDriven namespace that provides configuration options for RabbitMqEventBus +- RabbitMqMessage class in the Savvyio.Extensions.RabbitMQ namespace that provides a base class for RabbitMQ message operations, including connection and channel management, marshalling, and resource disposal while ensuring thread-safe initialization of RabbitMQ connectivity +- RabbitMqMessageOptions class in the Savvyio.Extensions.RabbitMQ namespace that provides configuration options for RabbitMqMessage + ## [4.0.3] - 2025-05-28 This is a service update that primarily focuses on package dependencies and minor improvements. From 36d198afba32a872b0ebc09dab6b006bb9f8d4d7 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:46:24 +0200 Subject: [PATCH 12/16] updated tests --- .../Commands/RabbitMqCommandQueueOptionsTest.cs | 3 +++ .../RabbitMqMessageOptionsTest.cs | 1 + 2 files changed, 4 insertions(+) diff --git a/test/Savvyio.Extensions.RabbitMQ.Tests/Commands/RabbitMqCommandQueueOptionsTest.cs b/test/Savvyio.Extensions.RabbitMQ.Tests/Commands/RabbitMqCommandQueueOptionsTest.cs index 4f9c618..55bf0ba 100644 --- a/test/Savvyio.Extensions.RabbitMQ.Tests/Commands/RabbitMqCommandQueueOptionsTest.cs +++ b/test/Savvyio.Extensions.RabbitMQ.Tests/Commands/RabbitMqCommandQueueOptionsTest.cs @@ -12,6 +12,9 @@ public void Constructor_Should_Set_Defaults() Assert.Null(options.QueueName); Assert.False(options.AutoAcknowledge); + Assert.False(options.Durable); + Assert.False(options.Exclusive); + Assert.False(options.AutoDelete); Assert.NotNull(options.AmqpUrl); // Inherited from RabbitMqMessageOptions } diff --git a/test/Savvyio.Extensions.RabbitMQ.Tests/RabbitMqMessageOptionsTest.cs b/test/Savvyio.Extensions.RabbitMQ.Tests/RabbitMqMessageOptionsTest.cs index 6fd4400..cea5cac 100644 --- a/test/Savvyio.Extensions.RabbitMQ.Tests/RabbitMqMessageOptionsTest.cs +++ b/test/Savvyio.Extensions.RabbitMQ.Tests/RabbitMqMessageOptionsTest.cs @@ -11,6 +11,7 @@ public void Constructor_Should_Set_Default_AmqpUrl() var options = new RabbitMqMessageOptions(); Assert.NotNull(options.AmqpUrl); + Assert.False(options.Persistent); Assert.Equal(new Uri("amqp://localhost:5672"), options.AmqpUrl); } From ce8e611f44b541b1ee13fb6e0e4812995d1c11a8 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:49:52 +0200 Subject: [PATCH 13/16] fix --- .github/workflows/pipelines.yml | 1 - .nuget/Savvyio.Extensions.RabbitMQ/PackageReleaseNotes.txt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/pipelines.yml b/.github/workflows/pipelines.yml index f4cf098..aebeb4e 100644 --- a/.github/workflows/pipelines.yml +++ b/.github/workflows/pipelines.yml @@ -65,7 +65,6 @@ jobs: uses: codebeltnet/jobs-dotnet-pack/.github/workflows/default.yml@v2 with: configuration: ${{ matrix.configuration }} - upload-packed-artifact: true version: ${{ needs.build.outputs.version }} test: diff --git a/.nuget/Savvyio.Extensions.RabbitMQ/PackageReleaseNotes.txt b/.nuget/Savvyio.Extensions.RabbitMQ/PackageReleaseNotes.txt index 41d4e3c..7985cf7 100644 --- a/.nuget/Savvyio.Extensions.RabbitMQ/PackageReleaseNotes.txt +++ b/.nuget/Savvyio.Extensions.RabbitMQ/PackageReleaseNotes.txt @@ -5,7 +5,7 @@ Availability: .NET 9 and .NET 8 - CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)   # New Features -- ADDED RabbitMqCommandQueue class in the Savvyio.Extensions.RabbitMQ.Commands namespace that provides a a default implementation of the RabbitMqMessage class for messages holding an ICommand implementation +- ADDED RabbitMqCommandQueue class in the Savvyio.Extensions.RabbitMQ.Commands namespace that provides a default implementation of the RabbitMqMessage class for messages holding an ICommand implementation - ADDED RabbitMqCommandQueueOptions class in the Savvyio.Extensions.RabbitMQ.Commands namespace that provides configuration options for RabbitMqCommandQueue - ADDED RabbitMqEventBus class in the Savvyio.Extensions.RabbitMQ.EventDriven namespace that provides a default implementation of the RabbitMqMessage class for messages holding an IIntegrationEvent implementation - ADDED RabbitMqEventBusOptions class in the Savvyio.Extensions.RabbitMQ.EventDriven namespace that provides configuration options for RabbitMqEventBus From c79a2dcebcee8f23d65294b534f56c8c46983854 Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:52:59 +0200 Subject: [PATCH 14/16] fix --- .github/workflows/pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pipelines.yml b/.github/workflows/pipelines.yml index aebeb4e..cb29597 100644 --- a/.github/workflows/pipelines.yml +++ b/.github/workflows/pipelines.yml @@ -148,6 +148,7 @@ jobs: uses: codebeltnet/dotnet-test@v4 with: projects: test/**/Savvyio.Extensions.RabbitMQ.FunctionalTests.csproj + build-switches: -p:SkipSignAssembly=true - name: Stop RabbitMQ run: | From 28c455e9fa939d1c7f65f20d04eaa4b2ce91d21d Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 20:57:05 +0200 Subject: [PATCH 15/16] fix --- .github/workflows/pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pipelines.yml b/.github/workflows/pipelines.yml index cb29597..759e7d3 100644 --- a/.github/workflows/pipelines.yml +++ b/.github/workflows/pipelines.yml @@ -152,8 +152,8 @@ jobs: - name: Stop RabbitMQ run: | - docker stop --name rabbitmq - docker rm --name rabbitmq + docker stop rabbitmq + docker rm rabbitmq sonarcloud: name: call-sonarcloud From 0c131fdf02492ddcadc74a6045b06ea08bc9ea6f Mon Sep 17 00:00:00 2001 From: Michael Mortensen Date: Mon, 9 Jun 2025 21:29:43 +0200 Subject: [PATCH 16/16] sync --- .../Commands/RabbitMqCommandQueue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs index 966a0e7..5ea45d4 100644 --- a/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs +++ b/src/Savvyio.Extensions.RabbitMQ/Commands/RabbitMqCommandQueue.cs @@ -116,7 +116,7 @@ private async Task OnMessageAcknowledgedAsync(object sender, AcknowledgedEventAr { var ct = (CancellationToken)e.Properties[nameof(CancellationToken)]; var queueName = e.Properties[nameof(QueueDeclareOk.QueueName)] as string; - await RabbitMqChannel.QueueDeclareAsync(queueName, false, false, false, cancellationToken: ct).ConfigureAwait(false); + await RabbitMqChannel.QueueDeclareAsync(queueName, _options.Durable, _options.Exclusive, _options.AutoDelete, cancellationToken: ct).ConfigureAwait(false); await RabbitMqChannel.BasicAckAsync((ulong)e.Properties[nameof(BasicDeliverEventArgs.DeliveryTag)], false, ct).ConfigureAwait(false); } }