From a799296da1b3c992e41e747a5d29a7fe0385e33a Mon Sep 17 00:00:00 2001 From: Lewis Renfrew Date: Thu, 28 May 2026 16:22:40 +0100 Subject: [PATCH 1/2] chlog --- changelog.md | 6 ++++++ src/Linn.Common.Messaging.RabbitMQ.csproj | 3 ++- src/RabbitMessageRouter.cs | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/changelog.md b/changelog.md index c380e03..3326672 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # Changelog +## [5.3.0] - 2026-05-28 +### *Changes (Breaking)* +- RabbitMessageRouter now takes `IServiceProvider` instead of `IEnumerable` and creates a DI scope per received message. This ensures scoped services (e.g. DbContext) are fresh for each message, preventing stale tracked entities from leaking across messages. +- Consumers must register handlers as Scoped (not Singleton) and pass `IServiceProvider` to the router. +- Added `Microsoft.Extensions.DependencyInjection.Abstractions` dependency. + ## [5.2.0] - 2026-05-19 ### *Changes* - Make JsonMessageHandler.HandleAsync(T, headers, ct) public instead of protected, allowing consuming applications to unit test their handler implementations directly with typed payloads rather than having to construct serialised Message objects diff --git a/src/Linn.Common.Messaging.RabbitMQ.csproj b/src/Linn.Common.Messaging.RabbitMQ.csproj index 6b37234..191e12f 100644 --- a/src/Linn.Common.Messaging.RabbitMQ.csproj +++ b/src/Linn.Common.Messaging.RabbitMQ.csproj @@ -5,11 +5,12 @@ enable Linn.Common.Messaging.RabbitMQ Linn.Common.Messaging.RabbitMQ - 5.2.0 + 5.3.0 enable + diff --git a/src/RabbitMessageRouter.cs b/src/RabbitMessageRouter.cs index df37634..79233bd 100644 --- a/src/RabbitMessageRouter.cs +++ b/src/RabbitMessageRouter.cs @@ -1,4 +1,5 @@ -using RabbitMQ.Client; +using Microsoft.Extensions.DependencyInjection; +using RabbitMQ.Client; using RabbitMQ.Client.Events; namespace Linn.Common.Messaging.RabbitMQ; @@ -6,19 +7,14 @@ namespace Linn.Common.Messaging.RabbitMQ; public class RabbitMessageRouter { private readonly IChannel channel; - private readonly Dictionary handlers; + private readonly IServiceProvider serviceProvider; public RabbitMessageRouter( IChannel channel, - IEnumerable handlers) + IServiceProvider serviceProvider) { this.channel = channel; - - this.handlers = handlers - .GroupBy(h => h.RoutingKey) - .ToDictionary( - g => g.Key, - g => g.Single()); + this.serviceProvider = serviceProvider; } public AsyncEventingBasicConsumer CreateConsumer( @@ -28,7 +24,11 @@ public AsyncEventingBasicConsumer CreateConsumer( consumer.ReceivedAsync += async (_, ea) => { - if (!this.handlers.TryGetValue(ea.RoutingKey, out var handler)) + await using var scope = this.serviceProvider.CreateAsyncScope(); + var handler = scope.ServiceProvider.GetServices() + .FirstOrDefault(h => h.RoutingKey == ea.RoutingKey); + + if (handler == null) { Console.WriteLine( $"No handler registered for routing key '{ea.RoutingKey}'"); From d83a49b7583e748bcc244cfdc72de004bbdac618 Mon Sep 17 00:00:00 2001 From: Lewis Renfrew Date: Thu, 28 May 2026 16:26:10 +0100 Subject: [PATCH 2/2] breaking so major version --- changelog.md | 2 +- src/Linn.Common.Messaging.RabbitMQ.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 3326672..1c88dd1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,6 @@ # Changelog -## [5.3.0] - 2026-05-28 +## [6.0.0] - 2026-05-28 ### *Changes (Breaking)* - RabbitMessageRouter now takes `IServiceProvider` instead of `IEnumerable` and creates a DI scope per received message. This ensures scoped services (e.g. DbContext) are fresh for each message, preventing stale tracked entities from leaking across messages. - Consumers must register handlers as Scoped (not Singleton) and pass `IServiceProvider` to the router. diff --git a/src/Linn.Common.Messaging.RabbitMQ.csproj b/src/Linn.Common.Messaging.RabbitMQ.csproj index 191e12f..5f13cc7 100644 --- a/src/Linn.Common.Messaging.RabbitMQ.csproj +++ b/src/Linn.Common.Messaging.RabbitMQ.csproj @@ -5,7 +5,7 @@ enable Linn.Common.Messaging.RabbitMQ Linn.Common.Messaging.RabbitMQ - 5.3.0 + 6.0.0 enable