From bf5bbd0774207edbf9ca53ebba514c11123a9822 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Fri, 8 May 2026 15:47:43 +0200 Subject: [PATCH 01/19] Use alpha --- src/Directory.Packages.props | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 5812e0a930..6b437ad4bc 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -34,7 +34,7 @@ - + @@ -52,7 +52,7 @@ - + @@ -94,4 +94,4 @@ - + \ No newline at end of file From 71f19ec9e2b1778cdb0392c71365c2b86cf673aa Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Fri, 8 May 2026 15:47:53 +0200 Subject: [PATCH 02/19] Remove no longer needed extension methods --- .../BasicEndpointSetup.cs | 1 - .../EndpointTestExtensions.cs | 24 ------------------- 2 files changed, 25 deletions(-) delete mode 100644 src/ServiceControl.Transports.Tests/EndpointTestExtensions.cs diff --git a/src/ServiceControl.Transports.Tests/BasicEndpointSetup.cs b/src/ServiceControl.Transports.Tests/BasicEndpointSetup.cs index 95bda2b31b..f31fe1a75e 100644 --- a/src/ServiceControl.Transports.Tests/BasicEndpointSetup.cs +++ b/src/ServiceControl.Transports.Tests/BasicEndpointSetup.cs @@ -15,7 +15,6 @@ public async Task GetConfiguration(RunDescriptor runDescr var endpointConfiguration = new EndpointConfiguration(endpointCustomization.EndpointName); endpointConfiguration.UseSerialization(); - endpointConfiguration.RegisterComponentsAndInheritanceHierarchy(runDescriptor); var recoverability = endpointConfiguration.Recoverability(); recoverability.Immediate(c => c.NumberOfRetries(3)); diff --git a/src/ServiceControl.Transports.Tests/EndpointTestExtensions.cs b/src/ServiceControl.Transports.Tests/EndpointTestExtensions.cs deleted file mode 100644 index 828d187339..0000000000 --- a/src/ServiceControl.Transports.Tests/EndpointTestExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace ServiceControl.Transport.Tests -{ - using System; - using Microsoft.Extensions.DependencyInjection; - using NServiceBus; - using NServiceBus.AcceptanceTesting.Support; - - public static class EndpointTestExtensions - { - public static void RegisterComponentsAndInheritanceHierarchy(this EndpointConfiguration builder, RunDescriptor runDescriptor) => builder.RegisterComponents( - services => { RegisterInheritanceHierarchyOfContextOnContainer(runDescriptor, services); }); - - static void RegisterInheritanceHierarchyOfContextOnContainer(RunDescriptor runDescriptor, - IServiceCollection services) - { - Type type = runDescriptor.ScenarioContext.GetType(); - while (type != typeof(object)) - { - services.AddSingleton(type, runDescriptor.ScenarioContext); - type = type.BaseType; - } - } - } -} \ No newline at end of file From 19eb5b239b5f3e2b985a3240fcf8aba0faafa439 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Fri, 8 May 2026 15:49:25 +0200 Subject: [PATCH 03/19] Acceptance testing alpha --- src/Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 6b437ad4bc..715e512064 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -35,7 +35,7 @@ - + From 033c1f8a5509b34bf8e71b99da5e41c03ca121c2 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Fri, 8 May 2026 16:02:18 +0200 Subject: [PATCH 04/19] RegisterComponent --- .../EndpointConfigurationExtensions.cs | 14 -------------- .../EndpointTemplates/DefaultServerBase.cs | 1 - .../When_encountered_an_error.cs | 4 ++-- .../When_errors_with_same_uniqueid_are_imported.cs | 6 +++--- ...ge_without_a_correlationid_header_is_retried.cs | 2 +- .../When_single_message_fails_in_batch.cs | 7 ++----- .../TestSupport/EndpointConfigurationExtensions.cs | 6 ------ .../TestSupport/EndpointConfigurationExtensions.cs | 6 ------ .../TestSupport/EndpointConfigurationExtensions.cs | 7 ------- .../Auditing/When_requesting_a_message_body.cs | 8 ++------ 10 files changed, 10 insertions(+), 51 deletions(-) diff --git a/src/ServiceControl.AcceptanceTesting/EndpointConfigurationExtensions.cs b/src/ServiceControl.AcceptanceTesting/EndpointConfigurationExtensions.cs index bc7935a031..8998e768d7 100644 --- a/src/ServiceControl.AcceptanceTesting/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.AcceptanceTesting/EndpointConfigurationExtensions.cs @@ -6,7 +6,6 @@ using System.Reflection; using System.Threading.Tasks; using InfrastructureConfig; - using Microsoft.Extensions.DependencyInjection; using NServiceBus; using NServiceBus.AcceptanceTesting.Customization; using NServiceBus.AcceptanceTesting.Support; @@ -62,19 +61,6 @@ public static async Task DefinePersistence(this EndpointConfiguration config, Ru runDescriptor.OnTestCompleted(_ => persistenceConfiguration.Cleanup()); } - public static void RegisterComponentsAndInheritanceHierarchy(this EndpointConfiguration builder, RunDescriptor runDescriptor) => builder.RegisterComponents(services => { RegisterInheritanceHierarchyOfContextOnContainer(runDescriptor, services); }); - - static void RegisterInheritanceHierarchyOfContextOnContainer(RunDescriptor runDescriptor, - IServiceCollection services) - { - var type = runDescriptor.ScenarioContext.GetType(); - while (type != typeof(object)) - { - services.AddSingleton(type, runDescriptor.ScenarioContext); - type = type.BaseType; - } - } - public static void NoImmediateRetries(this EndpointConfiguration configuration) => configuration.Recoverability().Immediate(x => x.NumberOfRetries(0)); diff --git a/src/ServiceControl.AcceptanceTesting/EndpointTemplates/DefaultServerBase.cs b/src/ServiceControl.AcceptanceTesting/EndpointTemplates/DefaultServerBase.cs index 68361944bd..a045a88345 100644 --- a/src/ServiceControl.AcceptanceTesting/EndpointTemplates/DefaultServerBase.cs +++ b/src/ServiceControl.AcceptanceTesting/EndpointTemplates/DefaultServerBase.cs @@ -30,7 +30,6 @@ public virtual async Task GetConfiguration(RunDescriptor await endpointTestExecutionConfiguration.Configure(endpointCustomizations.EndpointName, endpointConfiguration, runDescriptor.Settings, endpointCustomizations.PublisherMetadata); runDescriptor.OnTestCompleted(_ => endpointTestExecutionConfiguration.Cleanup()); - endpointConfiguration.RegisterComponentsAndInheritanceHierarchy(runDescriptor); await endpointConfiguration.DefinePersistence(runDescriptor, endpointCustomizations); endpointConfiguration.UseSerialization(); diff --git a/src/ServiceControl.AcceptanceTests/Recoverability/ExternalIntegration/When_encountered_an_error.cs b/src/ServiceControl.AcceptanceTests/Recoverability/ExternalIntegration/When_encountered_an_error.cs index c4401d3d3d..a50af7fb49 100644 --- a/src/ServiceControl.AcceptanceTests/Recoverability/ExternalIntegration/When_encountered_an_error.cs +++ b/src/ServiceControl.AcceptanceTests/Recoverability/ExternalIntegration/When_encountered_an_error.cs @@ -28,6 +28,8 @@ public async Task Should_restart_dispatch_thread() { var externalProcessorSubscribed = false; + CustomizeHostBuilder = builder => builder.Services.AddSingleton(); + CustomConfiguration = config => { config.OnEndpointSubscribed((s, ctx) => @@ -37,8 +39,6 @@ public async Task Should_restart_dispatch_thread() externalProcessorSubscribed = true; } }); - - config.RegisterComponents(services => services.AddSingleton()); }; ExecuteWhen(() => externalProcessorSubscribed, domainEvents => domainEvents.Raise(new EndpointFailedToHeartbeat diff --git a/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_errors_with_same_uniqueid_are_imported.cs b/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_errors_with_same_uniqueid_are_imported.cs index e777f23e93..58ad797ccd 100644 --- a/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_errors_with_same_uniqueid_are_imported.cs +++ b/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_errors_with_same_uniqueid_are_imported.cs @@ -24,15 +24,15 @@ public async Task The_import_should_deduplicate_on_TimeOfFailure() { var criticalErrorExecuted = false; - SetSettings = settings => { settings.MaximumConcurrencyLevel = 10; }; + SetSettings = settings => settings.MaximumConcurrencyLevel = 10; + CustomizeHostBuilder = builder => builder.Services.AddSingleton(); CustomConfiguration = config => { - config.DefineCriticalErrorAction((_, __) => + config.DefineCriticalErrorAction((_, _) => { criticalErrorExecuted = true; return Task.CompletedTask; }); - config.RegisterComponents(services => services.AddSingleton()); }; FailedMessage failure = null; diff --git a/src/ServiceControl.AcceptanceTests/Recoverability/When_a_message_without_a_correlationid_header_is_retried.cs b/src/ServiceControl.AcceptanceTests/Recoverability/When_a_message_without_a_correlationid_header_is_retried.cs index 1426e3133d..e382021977 100644 --- a/src/ServiceControl.AcceptanceTests/Recoverability/When_a_message_without_a_correlationid_header_is_retried.cs +++ b/src/ServiceControl.AcceptanceTests/Recoverability/When_a_message_without_a_correlationid_header_is_retried.cs @@ -64,7 +64,7 @@ public Receiver() => EndpointSetup(c => { c.NoRetries(); - c.RegisterComponents(services => services.AddSingleton()); + c.RegisterMessageMutator(new CorrelationIdRemover()); }); public class MyMessageHandler(MyContext testContext, IReadOnlySettings settings) diff --git a/src/ServiceControl.AcceptanceTests/Recoverability/When_single_message_fails_in_batch.cs b/src/ServiceControl.AcceptanceTests/Recoverability/When_single_message_fails_in_batch.cs index a89013e2d4..1e90dac10b 100644 --- a/src/ServiceControl.AcceptanceTests/Recoverability/When_single_message_fails_in_batch.cs +++ b/src/ServiceControl.AcceptanceTests/Recoverability/When_single_message_fails_in_batch.cs @@ -24,14 +24,11 @@ class When_single_message_fails_in_batch : AcceptanceTest public async Task Should_import_all_messages() { //Make sure the error import attempt fails - CustomConfiguration = config => { config.RegisterComponents(services => services.AddSingleton()); }; + CustomizeHostBuilder = builder => builder.Services.AddSingleton(); var maximumConcurrencyLevel = 5; - SetSettings = settings => - { - settings.MaximumConcurrencyLevel = maximumConcurrencyLevel; - }; + SetSettings = settings => settings.MaximumConcurrencyLevel = maximumConcurrencyLevel; await Define(ctx => { diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index 39b6bf46e3..20b76dfa30 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -19,12 +19,6 @@ public static void CustomizeServiceControlEndpointTesting(this EndpointConfigura configuration.GetSettings().Set("SC.ScenarioContext", context); configuration.GetSettings().Set(context); - configuration.RegisterComponents(r => - { - r.AddSingleton(context.GetType(), context); - r.AddSingleton(typeof(ScenarioContext), context); - }); - configuration.Pipeline.Register(); configuration.Pipeline.Register(); configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index 7525f93e11..37e62a0c71 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -14,12 +14,6 @@ public static void CustomizeServiceControlAuditEndpointTesting(this EndpointConf configuration.GetSettings().Set("SC.ScenarioContext", context); configuration.GetSettings().Set(context); - configuration.RegisterComponents(r => - { - r.AddSingleton(context.GetType(), context); - r.AddSingleton(typeof(ScenarioContext), context); - }); - configuration.Pipeline.Register(); configuration.Pipeline.Register(); configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index a995c4e850..366f474f13 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -2,7 +2,6 @@ namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport; using System.IO; using AcceptanceTesting; -using Microsoft.Extensions.DependencyInjection; using NServiceBus; using NServiceBus.AcceptanceTesting; using NServiceBus.Configuration.AdvancedExtensibility; @@ -14,12 +13,6 @@ public static void CustomizeServiceControlMonitoringEndpointTesting(this Endpoin configuration.GetSettings().Set("SC.ScenarioContext", context); configuration.GetSettings().Set(context); - configuration.RegisterComponents(r => - { - r.AddSingleton(context.GetType(), context); - r.AddSingleton(typeof(ScenarioContext), context); - }); - configuration.Pipeline.Register(); configuration.Pipeline.Register(); configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); diff --git a/src/ServiceControl.MultiInstance.AcceptanceTests/Auditing/When_requesting_a_message_body.cs b/src/ServiceControl.MultiInstance.AcceptanceTests/Auditing/When_requesting_a_message_body.cs index f38e5f3414..7a8df6b7de 100644 --- a/src/ServiceControl.MultiInstance.AcceptanceTests/Auditing/When_requesting_a_message_body.cs +++ b/src/ServiceControl.MultiInstance.AcceptanceTests/Auditing/When_requesting_a_message_body.cs @@ -92,14 +92,10 @@ class MyMessage : ICommand class RemoteEndpoint : EndpointConfigurationBuilder { - public RemoteEndpoint() => EndpointSetup(c => c.RegisterComponents(services => services.AddSingleton())); + public RemoteEndpoint() => EndpointSetup((c, context) => c.RegisterMessageMutator(new MessageBodySpy(context))); - public class MessageBodySpy : IMutateIncomingTransportMessages + public class MessageBodySpy(MyContext testContext) : IMutateIncomingTransportMessages { - readonly MyContext testContext; - - public MessageBodySpy(MyContext testContext) => this.testContext = testContext; - public Task MutateIncoming(MutateIncomingTransportMessageContext context) { testContext.MessageContentType = context.Headers[Headers.ContentType]; From 49d6c73767bb42bd317776688b19a5306444d991 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Sun, 10 May 2026 14:19:37 +0200 Subject: [PATCH 05/19] Replace `errorContext.Message` with direct `errorContext` usage. --- .../Auditing/AuditIngestionFaultPolicy.cs | 8 ++++---- src/ServiceControl.Audit/Auditing/Metrics/ErrorMetrics.cs | 2 +- .../Operations/ErrorIngestionFaultPolicy.cs | 6 +++--- .../Retrying/Infrastructure/ReturnToSenderDequeuer.cs | 5 ++--- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs b/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs index 02c55db1a9..b4952bff6c 100644 --- a/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs +++ b/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs @@ -59,12 +59,12 @@ async Task StoreFailedMessageDocument(ErrorContext errorContext, CancellationTok Id = Guid.NewGuid().ToString(), Message = new FailedTransportMessage { - Id = errorContext.Message.MessageId, - Headers = errorContext.Message.Headers, + Id = errorContext.MessageId, + Headers = errorContext.Headers, // At the moment we are taking a defensive copy of the body to avoid issues with the message body // buffers being returned to the pool and potentially being overwritten. Once we know how RavenDB - // handles byte[] to ReadOnlyMemory conversion we might be able to remove this. - Body = errorContext.Message.Body.ToArray() + // handles byte[] to ReadOnlyMemory conversion, we might be able to remove this. + Body = errorContext.Body.ToArray() }, ExceptionInfo = errorContext.Exception.ToFriendlyString() }; diff --git a/src/ServiceControl.Audit/Auditing/Metrics/ErrorMetrics.cs b/src/ServiceControl.Audit/Auditing/Metrics/ErrorMetrics.cs index f01e6a9293..6e5200b63d 100644 --- a/src/ServiceControl.Audit/Auditing/Metrics/ErrorMetrics.cs +++ b/src/ServiceControl.Audit/Auditing/Metrics/ErrorMetrics.cs @@ -8,7 +8,7 @@ public record ErrorMetrics(ErrorContext Context, Counter Failures) : IDisp { public void Dispose() { - var tags = IngestionMetrics.GetMessageTags(Context.Message.Headers); + var tags = IngestionMetrics.GetMessageTags(Context.Headers); tags.Add("result", retry ? "retry" : "stored-poison"); diff --git a/src/ServiceControl/Operations/ErrorIngestionFaultPolicy.cs b/src/ServiceControl/Operations/ErrorIngestionFaultPolicy.cs index 6562e2e22f..d60dae5c63 100644 --- a/src/ServiceControl/Operations/ErrorIngestionFaultPolicy.cs +++ b/src/ServiceControl/Operations/ErrorIngestionFaultPolicy.cs @@ -52,9 +52,9 @@ async Task Handle(ErrorContext errorContext, CancellationToken cancellationToken { Message = new FailedTransportMessage { - Id = errorContext.Message.MessageId, - Headers = errorContext.Message.Headers, - Body = errorContext.Message.Body.ToArray() + Id = errorContext.MessageId, + Headers = errorContext.Headers, + Body = errorContext.Body.ToArray() }, ExceptionInfo = errorContext.Exception.ToFriendlyString(), Id = FailedErrorImport.MakeDocumentId(Guid.NewGuid()) diff --git a/src/ServiceControl/Recoverability/Retrying/Infrastructure/ReturnToSenderDequeuer.cs b/src/ServiceControl/Recoverability/Retrying/Infrastructure/ReturnToSenderDequeuer.cs index 7bade70a97..d21d151738 100644 --- a/src/ServiceControl/Recoverability/Retrying/Infrastructure/ReturnToSenderDequeuer.cs +++ b/src/ServiceControl/Recoverability/Retrying/Infrastructure/ReturnToSenderDequeuer.cs @@ -197,9 +197,8 @@ public async Task OnError(ErrorContext errorContext, Cancella try { - var message = errorContext.Message; - var destination = message.Headers["ServiceControl.TargetEndpointAddress"]; - var messageUniqueId = message.Headers["ServiceControl.Retry.UniqueMessageId"]; + var destination = errorContext.Headers["ServiceControl.TargetEndpointAddress"]; + var messageUniqueId = errorContext.Headers["ServiceControl.Retry.UniqueMessageId"]; logger.LogWarning(errorContext.Exception, "Failed to send '{UniqueMessageId}' message to '{Destination}' for retry. Attempting to revert message status to unresolved so it can be tried again", messageUniqueId, destination); await dataStore.RevertRetry(messageUniqueId); From 86ba6180cf4e0a14c954c2639fbbcfb75191e76b Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Sun, 10 May 2026 14:25:13 +0200 Subject: [PATCH 06/19] LogManager.Use suppressions --- src/ServiceControl.Infrastructure/LoggingConfigurator.cs | 4 +++- src/ServiceControl.Transports.Tests/TransportTestFixture.cs | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ServiceControl.Infrastructure/LoggingConfigurator.cs b/src/ServiceControl.Infrastructure/LoggingConfigurator.cs index 53ad40b12e..d5646c2fe3 100644 --- a/src/ServiceControl.Infrastructure/LoggingConfigurator.cs +++ b/src/ServiceControl.Infrastructure/LoggingConfigurator.cs @@ -16,8 +16,10 @@ public static class LoggingConfigurator { public static void ConfigureLogging(LoggingSettings loggingSettings) { - //used for loggers outside of ServiceControl (i.e. transports and core) to use the logger factory defined here + //used for loggers outside ServiceControl (i.e. transports and core) to use the logger factory defined here +#pragma warning disable CS0618 // Type or member is obsolete LogManager.UseFactory(new ExtensionsLoggerFactory(LoggerFactory.Create(configure => configure.ConfigureLogging(loggingSettings.LogLevel)))); +#pragma warning restore CS0618 // Type or member is obsolete if (!LoggerUtil.IsLoggingTo(Loggers.NLog) || NLog.LogManager.Configuration != null) { diff --git a/src/ServiceControl.Transports.Tests/TransportTestFixture.cs b/src/ServiceControl.Transports.Tests/TransportTestFixture.cs index 0d4f82d592..7dd9bb23ea 100644 --- a/src/ServiceControl.Transports.Tests/TransportTestFixture.cs +++ b/src/ServiceControl.Transports.Tests/TransportTestFixture.cs @@ -30,7 +30,9 @@ abstract class TransportTestFixture public virtual async Task Setup() { //used for loggers outside ServiceControl (i.e. transports and core) to use the logger factory defined here +#pragma warning disable CS0618 // Type or member is obsolete LogManager.UseFactory(new ExtensionsLoggerFactory(new TestContextAppenderFactory(Microsoft.Extensions.Logging.LogLevel.Warning))); +#pragma warning restore CS0618 // Type or member is obsolete LoggerUtil.ActiveLoggers = Loggers.Test; configuration = new TransportTestsConfiguration(); testCancellationTokenSource = Debugger.IsAttached ? new CancellationTokenSource() : new CancellationTokenSource(TestTimeout); From e5058a18a276623731a89b0a1637082bfe454049 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Sun, 10 May 2026 16:18:50 +0200 Subject: [PATCH 07/19] RegisterScenarioContext method added --- .../TestSupport/EndpointConfigurationExtensions.cs | 4 ++-- .../TestSupport/EndpointConfigurationExtensions.cs | 4 ++-- .../TestSupport/EndpointConfigurationExtensions.cs | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index 20b76dfa30..cccc219a39 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -2,9 +2,9 @@ { using System.IO; using AcceptanceTesting; - using Microsoft.Extensions.DependencyInjection; using NServiceBus; using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTesting.Customization; using NServiceBus.Configuration.AdvancedExtensibility; public static class EndpointConfigurationExtensions @@ -17,7 +17,7 @@ public static void ReportSuccessfulRetriesToServiceControl(this EndpointConfigur public static void CustomizeServiceControlEndpointTesting(this EndpointConfiguration configuration, ScenarioContext context) { configuration.GetSettings().Set("SC.ScenarioContext", context); - configuration.GetSettings().Set(context); + configuration.RegisterScenarioContext(context); configuration.Pipeline.Register(); configuration.Pipeline.Register(); diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index 37e62a0c71..4b4ba5e2f8 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -2,9 +2,9 @@ namespace ServiceControl.Audit.AcceptanceTests.TestSupport; using System.IO; using AcceptanceTesting; -using Microsoft.Extensions.DependencyInjection; using NServiceBus; using NServiceBus.AcceptanceTesting; +using NServiceBus.AcceptanceTesting.Customization; using NServiceBus.Configuration.AdvancedExtensibility; static class EndpointConfigurationExtensions @@ -12,7 +12,7 @@ static class EndpointConfigurationExtensions public static void CustomizeServiceControlAuditEndpointTesting(this EndpointConfiguration configuration, ScenarioContext context) { configuration.GetSettings().Set("SC.ScenarioContext", context); - configuration.GetSettings().Set(context); + configuration.RegisterScenarioContext(context); configuration.Pipeline.Register(); configuration.Pipeline.Register(); diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index 366f474f13..cc90a8fb60 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -4,6 +4,7 @@ namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport; using AcceptanceTesting; using NServiceBus; using NServiceBus.AcceptanceTesting; +using NServiceBus.AcceptanceTesting.Customization; using NServiceBus.Configuration.AdvancedExtensibility; static class EndpointConfigurationExtensions @@ -11,7 +12,7 @@ static class EndpointConfigurationExtensions public static void CustomizeServiceControlMonitoringEndpointTesting(this EndpointConfiguration configuration, ScenarioContext context) { configuration.GetSettings().Set("SC.ScenarioContext", context); - configuration.GetSettings().Set(context); + configuration.RegisterScenarioContext(context); configuration.Pipeline.Register(); configuration.Pipeline.Register(); From 34198d43fdc1ddd5704d82b797ff5c494613862b Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Sun, 10 May 2026 16:20:09 +0200 Subject: [PATCH 08/19] Get the scenario context from settings for now and update registration class. --- .../TraceIncomingBehavior.cs | 20 +++---------------- .../TraceOutgoingBehavior.cs | 20 +++---------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/src/ServiceControl.AcceptanceTesting/TraceIncomingBehavior.cs b/src/ServiceControl.AcceptanceTesting/TraceIncomingBehavior.cs index 207d1de37d..493eb1b32e 100644 --- a/src/ServiceControl.AcceptanceTesting/TraceIncomingBehavior.cs +++ b/src/ServiceControl.AcceptanceTesting/TraceIncomingBehavior.cs @@ -8,16 +8,11 @@ namespace ServiceControl.AcceptanceTesting using NServiceBus.Pipeline; using NServiceBus.Settings; - public class TraceIncomingBehavior : IBehavior + public class TraceIncomingBehavior(IReadOnlySettings settings) : IBehavior { - public TraceIncomingBehavior(ScenarioContext scenarioContext, IReadOnlySettings settings) - { - this.scenarioContext = scenarioContext; - this.settings = settings; - } - public Task Invoke(IIncomingLogicalMessageContext context, Func next) { + var scenarioContext = settings.Get(); scenarioContext.Logs.Enqueue(new ScenarioContext.LogItem { Endpoint = settings.EndpointName(), @@ -28,15 +23,6 @@ public Task Invoke(IIncomingLogicalMessageContext context, Func + public class TraceOutgoingBehavior(IReadOnlySettings settings) : IBehavior { - public TraceOutgoingBehavior(ScenarioContext scenarioContext, IReadOnlySettings settings) - { - this.scenarioContext = scenarioContext; - this.settings = settings; - } - public Task Invoke(IOutgoingLogicalMessageContext context, Func next) { + var scenarioContext = settings.Get(); scenarioContext.Logs.Enqueue(new ScenarioContext.LogItem { Endpoint = settings.EndpointName(), @@ -28,15 +23,6 @@ public Task Invoke(IOutgoingLogicalMessageContext context, Func Date: Sun, 10 May 2026 16:20:48 +0200 Subject: [PATCH 09/19] Adjust to local build and update service resolve --- .../When_querying_disconnected_count.cs | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/When_querying_disconnected_count.cs b/src/ServiceControl.Monitoring.AcceptanceTests/When_querying_disconnected_count.cs index 52e60e9205..0366700b41 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/When_querying_disconnected_count.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/When_querying_disconnected_count.cs @@ -1,12 +1,15 @@ namespace ServiceControl.Monitoring.AcceptanceTests.Tests { using System; + using System.Threading; using System.Threading.Tasks; using AcceptanceTesting.EndpointTemplates; + using Microsoft.Extensions.DependencyInjection; using NServiceBus; using NServiceBus.AcceptanceTesting; using NUnit.Framework; using ServiceControl.AcceptanceTesting; + using Conventions = NServiceBus.AcceptanceTesting.Customization.Conventions; class When_querying_disconnected_count : AcceptanceTest { @@ -15,26 +18,22 @@ public async Task Should_report_via_http() { TestContext context = null; - SetSettings = settings => - { - settings.EndpointUptimeGracePeriod = TimeSpan.FromSeconds(1); - }; + SetSettings = settings => settings.EndpointUptimeGracePeriod = TimeSpan.FromSeconds(1); await Define(ctx => context = ctx) .WithEndpoint(b => - b.CustomConfig(c => c.EnableMetrics().SendMetricDataToServiceControl(Settings.DEFAULT_INSTANCE_NAME, TimeSpan.FromMilliseconds(200), "First")) - .ToCreateInstance((services, configuration) => EndpointWithExternallyManagedContainer.Create(configuration, services), async (startableEndpoint, provider, ct) => - { - context.FirstInstance = await startableEndpoint.Start(provider, ct); - return context.FirstInstance; - })) + b.CustomConfig(c => c.EnableMetrics().SendMetricDataToServiceControl(Settings.DEFAULT_INSTANCE_NAME, TimeSpan.FromMilliseconds(200), "First"))) .WithEndpoint(b => - b.CustomConfig(c => c.EnableMetrics().SendMetricDataToServiceControl(Settings.DEFAULT_INSTANCE_NAME, TimeSpan.FromMilliseconds(200), "Second")) - .ToCreateInstance((services, configuration) => EndpointWithExternallyManagedContainer.Create(configuration, services), async (startableEndpoint, provider, ct) => - { - context.SecondInstance = await startableEndpoint.Start(provider, ct); - return context.SecondInstance; - })) + b.CustomConfig(c => c.EnableMetrics().SendMetricDataToServiceControl(Settings.DEFAULT_INSTANCE_NAME, TimeSpan.FromMilliseconds(200), "Second"))) + .WithServiceResolve(static (provider, context, _) => + { + var endpointName = Conventions.EndpointNamingConvention(typeof(MonitoredEndpoint)); + context.StopFirstInstance = provider.GetRequiredKeyedService>( + new KeyedServiceKey($"{endpointName}1", "Stopper")); + context.StopSecondInstance = provider.GetRequiredKeyedService>( + new KeyedServiceKey($"{endpointName}2", "Stopper")); + return Task.CompletedTask; + }) .Done(async c => { if (!c.WaitedInitial2Seconds) @@ -57,7 +56,7 @@ await Define(ctx => context = ctx) if (!c.StoppedFirstInstance) { c.AfterAllStartedCount = disconnectedCount; - await c.FirstInstance.Stop(); + await c.StopFirstInstance(CancellationToken.None); c.StoppedFirstInstance = true; await Task.Delay(2000); return false; @@ -66,7 +65,7 @@ await Define(ctx => context = ctx) if (!c.StoppedSecondInstance) { c.AfterFirstStoppedCount = disconnectedCount; - await c.SecondInstance.Stop(); + await c.StopSecondInstance(CancellationToken.None); c.StoppedSecondInstance = true; await Task.Delay(2000); return false; @@ -77,12 +76,12 @@ await Define(ctx => context = ctx) }) .Run(); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(context.AfterAllStartedCount, Is.EqualTo(0), "Disconnected count after all endpoints started"); Assert.That(context.AfterFirstStoppedCount, Is.EqualTo(0), "Disconnected count after first endpoint stopped"); Assert.That(context.AfterSecondStoppedCount, Is.EqualTo(1), "Disconnected count after both endpoints stopped"); - }); + } } class MonitoredEndpoint : EndpointConfigurationBuilder @@ -93,13 +92,13 @@ class MonitoredEndpoint : EndpointConfigurationBuilder class TestContext : ScenarioContext { public bool WaitedInitial2Seconds { get; set; } - public IEndpointInstance FirstInstance { get; set; } + public Func StopFirstInstance { get; set; } public bool StoppedFirstInstance { get; set; } - public IEndpointInstance SecondInstance { get; set; } + public Func StopSecondInstance { get; set; } public bool StoppedSecondInstance { get; set; } public int AfterAllStartedCount { get; set; } = int.MinValue; //So we know if there is a logical failure, not a zero was returned public int AfterFirstStoppedCount { get; set; } = int.MinValue; public int AfterSecondStoppedCount { get; set; } = int.MinValue; } } -} +} \ No newline at end of file From 9a639d547e07c25b96df5e46716101e752941999 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 10:41:54 +0200 Subject: [PATCH 10/19] Add ScenarioContext to host builder for dependency resolution --- .../TestSupport/ServiceControlComponentRunner.cs | 3 +++ .../TestSupport/ServiceControlComponentRunner.cs | 2 ++ .../TestSupport/ServiceControlComponentRunner.cs | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index 657a84244d..1b607e84ec 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -21,6 +21,7 @@ using Microsoft.Extensions.Logging; using NServiceBus; using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTesting.Customization; using NServiceBus.AcceptanceTesting.Support; using Particular.ServiceControl; using Particular.ServiceControl.Hosting; @@ -122,6 +123,8 @@ async Task InitializeServiceControl(ScenarioContext context) // Force the DI container to run the dependency resolution check to verify all dependencies can be resolved EnvironmentName = Environments.Development }); + + hostBuilder.Services.AddScenarioContext(context); hostBuilder.AddServiceControlAuthentication(settings.OpenIdConnectSettings); hostBuilder.AddServiceControl(settings, configuration); hostBuilder.AddServiceControlHttps(settings.HttpsSettings); diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index efcd99c0f6..041ef4a5fc 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -23,6 +23,7 @@ namespace ServiceControl.Audit.AcceptanceTests.TestSupport using ServiceControl.Hosting.Auth; using ServiceControl.Hosting.Https; using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTesting.Customization; using NServiceBus.AcceptanceTesting.Support; using ServiceControl.Infrastructure; @@ -119,6 +120,7 @@ async Task InitializeServiceControl(ScenarioContext context) // Force the DI container to run the dependency resolution check to verify all dependencies can be resolved EnvironmentName = Environments.Development }); + hostBuilder.Services.AddScenarioContext(context); hostBuilder.AddServiceControlAuthentication(settings.OpenIdConnectSettings); hostBuilder.AddServiceControlAudit((criticalErrorContext, cancellationToken) => { diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index 1d233e7cc7..63d3a1141e 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -20,6 +20,7 @@ namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport using ServiceControl.Hosting.Auth; using ServiceControl.Hosting.Https; using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTesting.Customization; using NServiceBus.AcceptanceTesting.Support; using ServiceControl.Infrastructure; @@ -99,6 +100,8 @@ async Task InitializeServiceControl(ScenarioContext context) hostBuilder.Logging.ClearProviders(); hostBuilder.Logging.ConfigureLogging(LogLevel.Information); + hostBuilder.Services.AddScenarioContext(context); + hostBuilder.AddServiceControlAuthentication(settings.OpenIdConnectSettings); hostBuilder.AddServiceControlMonitoring((criticalErrorContext, cancellationToken) => { From 4ddecf67d6f45ec8ffe90eec5b080905d3c66dda Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 11:05:32 +0200 Subject: [PATCH 11/19] Refactor message handler constructors to use parameterized constructors with [Handler] attribute --- .../Infrastructure/EndpointTracker.cs | 28 +++------------- .../Infrastructure/MessageTypeTracker.cs | 10 ++---- .../EndpointMetadataReportHandler.cs | 10 ++---- .../LegacyQueueLengthReportHandler.cs | 5 +-- .../QueueLength/QueueLengthReportHandler.cs | 10 ++---- .../TaggedLongValueOccurrenceHandler.cs | 9 ++--- .../TaggedLongValueOccurrenceHandler.cs | 1 + .../CustomChecks/DeleteCustomCheckHandler.cs | 12 ++----- .../ReportCustomCheckResultHandler.cs | 10 ++---- .../Handlers/ArchiveMessageHandler.cs | 12 ++----- .../LegacyMessageFailureResolvedHandler.cs | 12 ++----- .../Handlers/MessageFailureResolvedHandler.cs | 12 ++----- .../UnArchiveMessagesByRangeHandler.cs | 13 ++------ .../Handlers/UnArchiveMessagesHandler.cs | 1 + .../HeartbeatMonitoring/LegacyHandler.cs | 1 + .../RegisterEndpointStartupHandler.cs | 10 ++---- .../Monitoring/RegisterNewEndpointHandler.cs | 20 +++-------- .../Monitoring/Transport/HeartbeatHandler.cs | 10 ++---- .../MassTransitConnectorHeartbeatHandler.cs | 1 + .../Email/SendEmailNotificationHandler.cs | 33 +++++-------------- .../Archiving/ArchiveAllInGroupHandler.cs | 14 ++------ .../Archiving/UnArchiveAllInGroupHandler.cs | 14 ++------ .../Recoverability/Editing/EditHandler.cs | 24 +++----------- .../Handlers/PendingRetriesHandler.cs | 1 + .../Retrying/Handlers/RetriesHandler.cs | 22 +++---------- .../Handlers/RetryAllInGroupHandler.cs | 19 ++--------- .../RetryHandlerForBackwardsCompatability.cs | 14 +++----- .../SagaAudit/SagaUpdatedHandler.cs | 1 + 28 files changed, 70 insertions(+), 259 deletions(-) diff --git a/src/ServiceControl.Monitoring/Infrastructure/EndpointTracker.cs b/src/ServiceControl.Monitoring/Infrastructure/EndpointTracker.cs index 12fa86bb5b..389e6fd3d6 100644 --- a/src/ServiceControl.Monitoring/Infrastructure/EndpointTracker.cs +++ b/src/ServiceControl.Monitoring/Infrastructure/EndpointTracker.cs @@ -6,28 +6,14 @@ using NServiceBus; using NServiceBus.Metrics; - public class EndpointTracker : IHandleMessages, IHandleMessages, IHandleMessages + [Handler] + public class EndpointTracker(EndpointRegistry endpointRegistry, EndpointInstanceActivityTracker activityTracker) : IHandleMessages, IHandleMessages, IHandleMessages { - public EndpointTracker(EndpointRegistry endpointRegistry, EndpointInstanceActivityTracker activityTracker) - { - this.endpointRegistry = endpointRegistry; - this.activityTracker = activityTracker; - } + public Task Handle(EndpointMetadataReport message, IMessageHandlerContext context) => RecordEndpointInstanceId(context); - public Task Handle(EndpointMetadataReport message, IMessageHandlerContext context) - { - return RecordEndpointInstanceId(context); - } + public Task Handle(MetricReport message, IMessageHandlerContext context) => RecordEndpointInstanceId(context); - public Task Handle(MetricReport message, IMessageHandlerContext context) - { - return RecordEndpointInstanceId(context); - } - - public Task Handle(TaggedLongValueOccurrence message, IMessageHandlerContext context) - { - return RecordEndpointInstanceId(context); - } + public Task Handle(TaggedLongValueOccurrence message, IMessageHandlerContext context) => RecordEndpointInstanceId(context); Task RecordEndpointInstanceId(IMessageHandlerContext context) { @@ -38,9 +24,5 @@ Task RecordEndpointInstanceId(IMessageHandlerContext context) return Task.CompletedTask; } - - readonly EndpointInstanceActivityTracker activityTracker; - - EndpointRegistry endpointRegistry; } } \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/Infrastructure/MessageTypeTracker.cs b/src/ServiceControl.Monitoring/Infrastructure/MessageTypeTracker.cs index 9fc6623e85..935808ee2f 100644 --- a/src/ServiceControl.Monitoring/Infrastructure/MessageTypeTracker.cs +++ b/src/ServiceControl.Monitoring/Infrastructure/MessageTypeTracker.cs @@ -4,13 +4,9 @@ using Messaging; using NServiceBus; - public class MessageTypeTracker : IHandleMessages + [Handler] + public class MessageTypeTracker(MessageTypeRegistry registry) : IHandleMessages { - public MessageTypeTracker(MessageTypeRegistry registry) - { - this.registry = registry; - } - public Task Handle(TaggedLongValueOccurrence message, IMessageHandlerContext context) { var endpointName = context.MessageHeaders[Headers.OriginatingEndpoint]; @@ -19,7 +15,5 @@ public Task Handle(TaggedLongValueOccurrence message, IMessageHandlerContext con return Task.CompletedTask; } - - readonly MessageTypeRegistry registry; } } \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/QueueLength/EndpointMetadataReportHandler.cs b/src/ServiceControl.Monitoring/QueueLength/EndpointMetadataReportHandler.cs index 95201e1c9c..4d7d1126f5 100644 --- a/src/ServiceControl.Monitoring/QueueLength/EndpointMetadataReportHandler.cs +++ b/src/ServiceControl.Monitoring/QueueLength/EndpointMetadataReportHandler.cs @@ -5,13 +5,9 @@ using NServiceBus.Metrics; using Transports; - public class EndpointMetadataReportHandler : IHandleMessages + [Handler] + public class EndpointMetadataReportHandler(IProvideQueueLength queueLengthProvider) : IHandleMessages { - public EndpointMetadataReportHandler(IProvideQueueLength queueLengthProvider) - { - this.queueLengthProvider = queueLengthProvider; - } - public Task Handle(EndpointMetadataReport message, IMessageHandlerContext context) { var endpointName = context.MessageHeaders[Headers.OriginatingEndpoint]; @@ -20,7 +16,5 @@ public Task Handle(EndpointMetadataReport message, IMessageHandlerContext contex return Task.CompletedTask; } - - IProvideQueueLength queueLengthProvider; } } \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/QueueLength/LegacyQueueLengthReportHandler.cs b/src/ServiceControl.Monitoring/QueueLength/LegacyQueueLengthReportHandler.cs index 93d905558d..161009a410 100644 --- a/src/ServiceControl.Monitoring/QueueLength/LegacyQueueLengthReportHandler.cs +++ b/src/ServiceControl.Monitoring/QueueLength/LegacyQueueLengthReportHandler.cs @@ -9,6 +9,7 @@ using NServiceBus; using NServiceBus.Metrics; + [Handler] class LegacyQueueLengthReportHandler(LegacyQueueLengthReportHandler.LegacyQueueLengthEndpoints legacyEndpoints, ILogger logger) : IHandleMessages { public Task Handle(MetricReport message, IMessageHandlerContext context) @@ -39,9 +40,9 @@ public bool TryAdd(string id) return registeredInstances.TryAdd(id, id); } - ConcurrentDictionary registeredInstances = new ConcurrentDictionary(); + readonly ConcurrentDictionary registeredInstances = new ConcurrentDictionary(); long lastCleanTicks = DateTime.UtcNow.Ticks; - static long cleanIntervalTicks = TimeSpan.FromHours(1).Ticks; + static readonly long cleanIntervalTicks = TimeSpan.FromHours(1).Ticks; } } } \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/QueueLength/QueueLengthReportHandler.cs b/src/ServiceControl.Monitoring/QueueLength/QueueLengthReportHandler.cs index 66caa096a3..f007558c57 100644 --- a/src/ServiceControl.Monitoring/QueueLength/QueueLengthReportHandler.cs +++ b/src/ServiceControl.Monitoring/QueueLength/QueueLengthReportHandler.cs @@ -5,13 +5,9 @@ using Messaging; using NServiceBus; - public class QueueLengthReportHandler : IHandleMessages + [Handler] + public class QueueLengthReportHandler(QueueLengthStore queueLengthStore) : IHandleMessages { - public QueueLengthReportHandler(QueueLengthStore queueLengthStore) - { - this.queueLengthStore = queueLengthStore; - } - public Task Handle(TaggedLongValueOccurrence message, IMessageHandlerContext context) { var endpointName = context.MessageHeaders[Headers.OriginatingEndpoint]; @@ -26,8 +22,6 @@ public Task Handle(TaggedLongValueOccurrence message, IMessageHandlerContext con } - QueueLengthStore queueLengthStore; - const string QueueLengthMessageType = "QueueLength"; } } \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/Retries/TaggedLongValueOccurrenceHandler.cs b/src/ServiceControl.Monitoring/Retries/TaggedLongValueOccurrenceHandler.cs index d2d32baf94..1c6c0037c2 100644 --- a/src/ServiceControl.Monitoring/Retries/TaggedLongValueOccurrenceHandler.cs +++ b/src/ServiceControl.Monitoring/Retries/TaggedLongValueOccurrenceHandler.cs @@ -5,13 +5,9 @@ using Messaging; using NServiceBus; - public class TaggedLongValueOccurrenceHandler : IHandleMessages + [Handler] + public class TaggedLongValueOccurrenceHandler(RetriesStore store) : IHandleMessages { - public TaggedLongValueOccurrenceHandler(RetriesStore store) - { - this.store = store; - } - public Task Handle(TaggedLongValueOccurrence message, IMessageHandlerContext context) { var instanceId = EndpointInstanceId.From(context.MessageHeaders); @@ -25,7 +21,6 @@ public Task Handle(TaggedLongValueOccurrence message, IMessageHandlerContext con return Task.CompletedTask; } - readonly RetriesStore store; const string RetriesMessageType = "Retries"; } } \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/Timings/TaggedLongValueOccurrenceHandler.cs b/src/ServiceControl.Monitoring/Timings/TaggedLongValueOccurrenceHandler.cs index a8a254901d..267f7bbdf8 100644 --- a/src/ServiceControl.Monitoring/Timings/TaggedLongValueOccurrenceHandler.cs +++ b/src/ServiceControl.Monitoring/Timings/TaggedLongValueOccurrenceHandler.cs @@ -5,6 +5,7 @@ using Messaging; using NServiceBus; + [Handler] public class TaggedLongValueOccurrenceHandler : IHandleMessages { public TaggedLongValueOccurrenceHandler(ProcessingTimeStore processingTimeStore, CriticalTimeStore criticalTimeStore) diff --git a/src/ServiceControl/CustomChecks/DeleteCustomCheckHandler.cs b/src/ServiceControl/CustomChecks/DeleteCustomCheckHandler.cs index 79a3e1aa81..342fb039ea 100644 --- a/src/ServiceControl/CustomChecks/DeleteCustomCheckHandler.cs +++ b/src/ServiceControl/CustomChecks/DeleteCustomCheckHandler.cs @@ -5,22 +5,14 @@ using NServiceBus; using Persistence; - class DeleteCustomCheckHandler : IHandleMessages + [Handler] + class DeleteCustomCheckHandler(ICustomChecksDataStore customChecksDataStore, IDomainEvents domainEvents) : IHandleMessages { - public DeleteCustomCheckHandler(ICustomChecksDataStore customChecksDataStore, IDomainEvents domainEvents) - { - this.customChecksDataStore = customChecksDataStore; - this.domainEvents = domainEvents; - } - public async Task Handle(DeleteCustomCheck message, IMessageHandlerContext context) { await customChecksDataStore.DeleteCustomCheck(message.Id); await domainEvents.Raise(new CustomCheckDeleted { Id = message.Id }, context.CancellationToken); } - - ICustomChecksDataStore customChecksDataStore; - IDomainEvents domainEvents; } } \ No newline at end of file diff --git a/src/ServiceControl/CustomChecks/ReportCustomCheckResultHandler.cs b/src/ServiceControl/CustomChecks/ReportCustomCheckResultHandler.cs index 122b49ac74..f9cda8e083 100644 --- a/src/ServiceControl/CustomChecks/ReportCustomCheckResultHandler.cs +++ b/src/ServiceControl/CustomChecks/ReportCustomCheckResultHandler.cs @@ -7,13 +7,9 @@ using Plugin.CustomChecks.Messages; using ServiceControl.Operations; - class ReportCustomCheckResultHandler : IHandleMessages + [Handler] + class ReportCustomCheckResultHandler(CustomCheckResultProcessor checkResultProcessor) : IHandleMessages { - public ReportCustomCheckResultHandler(CustomCheckResultProcessor checkResultProcessor) - { - this.checkResultProcessor = checkResultProcessor; - } - public async Task Handle(ReportCustomCheckResult message, IMessageHandlerContext context) { if (string.IsNullOrEmpty(message.EndpointName)) @@ -48,7 +44,5 @@ public async Task Handle(ReportCustomCheckResult message, IMessageHandlerContext await checkResultProcessor.ProcessResult(checkDetails); } - - readonly CustomCheckResultProcessor checkResultProcessor; } } \ No newline at end of file diff --git a/src/ServiceControl/MessageFailures/Handlers/ArchiveMessageHandler.cs b/src/ServiceControl/MessageFailures/Handlers/ArchiveMessageHandler.cs index 2e317cba54..6bbdd411d3 100644 --- a/src/ServiceControl/MessageFailures/Handlers/ArchiveMessageHandler.cs +++ b/src/ServiceControl/MessageFailures/Handlers/ArchiveMessageHandler.cs @@ -7,14 +7,9 @@ using NServiceBus; using ServiceControl.Persistence; - class ArchiveMessageHandler : IHandleMessages + [Handler] + class ArchiveMessageHandler(IErrorMessageDataStore dataStore, IDomainEvents domainEvents) : IHandleMessages { - public ArchiveMessageHandler(IErrorMessageDataStore dataStore, IDomainEvents domainEvents) - { - this.dataStore = dataStore; - this.domainEvents = domainEvents; - } - public async Task Handle(ArchiveMessage message, IMessageHandlerContext context) { var failedMessageId = message.FailedMessageId; @@ -31,8 +26,5 @@ await domainEvents.Raise(new FailedMessageArchived await dataStore.FailedMessageMarkAsArchived(failedMessageId); } } - - IErrorMessageDataStore dataStore; - IDomainEvents domainEvents; } } \ No newline at end of file diff --git a/src/ServiceControl/MessageFailures/Handlers/LegacyMessageFailureResolvedHandler.cs b/src/ServiceControl/MessageFailures/Handlers/LegacyMessageFailureResolvedHandler.cs index 6c9e5f62db..6ae338fdc6 100644 --- a/src/ServiceControl/MessageFailures/Handlers/LegacyMessageFailureResolvedHandler.cs +++ b/src/ServiceControl/MessageFailures/Handlers/LegacyMessageFailureResolvedHandler.cs @@ -10,16 +10,11 @@ /// /// This class handles legacy messages that mark a failed message as successfully retried. For further details go to message definitions. /// - class LegacyMessageFailureResolvedHandler : + [Handler] + class LegacyMessageFailureResolvedHandler(IErrorMessageDataStore store, IDomainEvents domainEvents) : IHandleMessages, IHandleMessages { - public LegacyMessageFailureResolvedHandler(IErrorMessageDataStore store, IDomainEvents domainEvents) - { - this.store = store; - this.domainEvents = domainEvents; - } - public async Task Handle(MarkMessageFailureResolvedByRetry message, IMessageHandlerContext context) { await MarkAsResolvedByRetry(message.FailedMessageId, message.AlternativeFailedMessageIds); @@ -69,8 +64,5 @@ async Task MarkAsResolvedByRetry(string primaryId, string[] messageAlternativeFa } } } - - readonly IErrorMessageDataStore store; - readonly IDomainEvents domainEvents; } } \ No newline at end of file diff --git a/src/ServiceControl/MessageFailures/Handlers/MessageFailureResolvedHandler.cs b/src/ServiceControl/MessageFailures/Handlers/MessageFailureResolvedHandler.cs index 251123319d..031a66306a 100644 --- a/src/ServiceControl/MessageFailures/Handlers/MessageFailureResolvedHandler.cs +++ b/src/ServiceControl/MessageFailures/Handlers/MessageFailureResolvedHandler.cs @@ -7,16 +7,11 @@ using NServiceBus; using Persistence; - class MessageFailureResolvedHandler : + [Handler] + class MessageFailureResolvedHandler(IErrorMessageDataStore dataStore, IDomainEvents domainEvents) : IHandleMessages, IHandleMessages { - public MessageFailureResolvedHandler(IErrorMessageDataStore dataStore, IDomainEvents domainEvents) - { - this.dataStore = dataStore; - this.domainEvents = domainEvents; - } - public Task Handle(MarkPendingRetriesAsResolved message, IMessageHandlerContext context) { Task ProcessCallback(string id) @@ -46,8 +41,5 @@ await domainEvents.Raise(new MessageFailureResolvedManually FailedMessageId = message.FailedMessageId }, context.CancellationToken); } - - IErrorMessageDataStore dataStore; - IDomainEvents domainEvents; } } \ No newline at end of file diff --git a/src/ServiceControl/MessageFailures/Handlers/UnArchiveMessagesByRangeHandler.cs b/src/ServiceControl/MessageFailures/Handlers/UnArchiveMessagesByRangeHandler.cs index 2415e085bd..83eef58e5c 100644 --- a/src/ServiceControl/MessageFailures/Handlers/UnArchiveMessagesByRangeHandler.cs +++ b/src/ServiceControl/MessageFailures/Handlers/UnArchiveMessagesByRangeHandler.cs @@ -7,14 +7,9 @@ using NServiceBus; using Persistence; - class UnArchiveMessagesByRangeHandler : IHandleMessages + [Handler] + class UnArchiveMessagesByRangeHandler(IErrorMessageDataStore dataStore, IDomainEvents domainEvents) : IHandleMessages { - public UnArchiveMessagesByRangeHandler(IErrorMessageDataStore dataStore, IDomainEvents domainEvents) - { - this.dataStore = dataStore; - this.domainEvents = domainEvents; - } - public async Task Handle(UnArchiveMessagesByRange message, IMessageHandlerContext context) { var ids = await dataStore.UnArchiveMessagesByRange(message.From, message.To); @@ -26,9 +21,5 @@ await domainEvents.Raise(new FailedMessagesUnArchived }, context.CancellationToken); } - - IErrorMessageDataStore dataStore; - IDomainEvents domainEvents; - } } \ No newline at end of file diff --git a/src/ServiceControl/MessageFailures/Handlers/UnArchiveMessagesHandler.cs b/src/ServiceControl/MessageFailures/Handlers/UnArchiveMessagesHandler.cs index cb601ddbb4..b85f1a00e3 100644 --- a/src/ServiceControl/MessageFailures/Handlers/UnArchiveMessagesHandler.cs +++ b/src/ServiceControl/MessageFailures/Handlers/UnArchiveMessagesHandler.cs @@ -7,6 +7,7 @@ using NServiceBus; using Persistence; + [Handler] class UnArchiveMessagesHandler(IErrorMessageDataStore store, IDomainEvents domainEvents) : IHandleMessages { diff --git a/src/ServiceControl/Monitoring/HeartbeatMonitoring/LegacyHandler.cs b/src/ServiceControl/Monitoring/HeartbeatMonitoring/LegacyHandler.cs index 3116a7c595..356e977090 100644 --- a/src/ServiceControl/Monitoring/HeartbeatMonitoring/LegacyHandler.cs +++ b/src/ServiceControl/Monitoring/HeartbeatMonitoring/LegacyHandler.cs @@ -6,6 +6,7 @@ using InternalMessages; using NServiceBus; + [Handler] class LegacyHandler : IHandleMessages, IHandleMessages, IHandleMessages, diff --git a/src/ServiceControl/Monitoring/HeartbeatMonitoring/RegisterEndpointStartupHandler.cs b/src/ServiceControl/Monitoring/HeartbeatMonitoring/RegisterEndpointStartupHandler.cs index bebf96c75e..036f02d724 100644 --- a/src/ServiceControl/Monitoring/HeartbeatMonitoring/RegisterEndpointStartupHandler.cs +++ b/src/ServiceControl/Monitoring/HeartbeatMonitoring/RegisterEndpointStartupHandler.cs @@ -6,13 +6,9 @@ using ServiceControl.Operations; using ServiceControl.Persistence; - class RegisterEndpointStartupHandler : IHandleMessages + [Handler] + class RegisterEndpointStartupHandler(IEndpointInstanceMonitoring monitoring) : IHandleMessages { - public RegisterEndpointStartupHandler(IEndpointInstanceMonitoring monitoring) - { - this.monitoring = monitoring; - } - public Task Handle(RegisterEndpointStartup message, IMessageHandlerContext context) { var endpointDetails = new EndpointDetails @@ -23,7 +19,5 @@ public Task Handle(RegisterEndpointStartup message, IMessageHandlerContext conte }; return monitoring.DetectEndpointFromHeartbeatStartup(endpointDetails, message.StartedAt); } - - IEndpointInstanceMonitoring monitoring; } } \ No newline at end of file diff --git a/src/ServiceControl/Monitoring/RegisterNewEndpointHandler.cs b/src/ServiceControl/Monitoring/RegisterNewEndpointHandler.cs index 176a0eb0fd..087379f5f5 100644 --- a/src/ServiceControl/Monitoring/RegisterNewEndpointHandler.cs +++ b/src/ServiceControl/Monitoring/RegisterNewEndpointHandler.cs @@ -5,26 +5,14 @@ using NServiceBus; using ServiceControl.Persistence; - class RegisterNewEndpointHandler : + [Handler] + class RegisterNewEndpointHandler(IEndpointInstanceMonitoring endpointInstanceMonitoring) : IHandleMessages, IHandleMessages { - public RegisterNewEndpointHandler(IEndpointInstanceMonitoring endpointInstanceMonitoring) - { - this.endpointInstanceMonitoring = endpointInstanceMonitoring; - } - // for backward compatibility reasons - public Task Handle(NewEndpointDetected message, IMessageHandlerContext context) - { - return endpointInstanceMonitoring.EndpointDetected(message.Endpoint); - } - - public Task Handle(RegisterNewEndpoint message, IMessageHandlerContext context) - { - return endpointInstanceMonitoring.EndpointDetected(message.Endpoint); - } + public Task Handle(NewEndpointDetected message, IMessageHandlerContext context) => endpointInstanceMonitoring.EndpointDetected(message.Endpoint); - readonly IEndpointInstanceMonitoring endpointInstanceMonitoring; + public Task Handle(RegisterNewEndpoint message, IMessageHandlerContext context) => endpointInstanceMonitoring.EndpointDetected(message.Endpoint); } } \ No newline at end of file diff --git a/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs b/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs index ccb1675063..e8abdeb72d 100644 --- a/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs +++ b/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs @@ -5,13 +5,9 @@ using Plugin.Heartbeat.Messages; using ServiceControl.Persistence; - class HeartbeatHandler : IHandleMessages + [Handler] + class HeartbeatHandler(IEndpointInstanceMonitoring monitor) : IHandleMessages { - public HeartbeatHandler(IEndpointInstanceMonitoring monitor) - { - this.monitor = monitor; - } - public Task Handle(EndpointHeartbeat message, IMessageHandlerContext context) { var endpointInstanceId = new EndpointInstanceId(message.EndpointName, message.Host, message.HostId); @@ -20,7 +16,5 @@ public Task Handle(EndpointHeartbeat message, IMessageHandlerContext context) return Task.CompletedTask; } - - IEndpointInstanceMonitoring monitor; } } \ No newline at end of file diff --git a/src/ServiceControl/Monitoring/Transport/MassTransitConnectorHeartbeatHandler.cs b/src/ServiceControl/Monitoring/Transport/MassTransitConnectorHeartbeatHandler.cs index 68871aa92b..75607c49de 100644 --- a/src/ServiceControl/Monitoring/Transport/MassTransitConnectorHeartbeatHandler.cs +++ b/src/ServiceControl/Monitoring/Transport/MassTransitConnectorHeartbeatHandler.cs @@ -5,6 +5,7 @@ namespace ServiceControl.Monitoring; using HeartbeatMonitoring; using NServiceBus; +[Handler] class MassTransitConnectorHeartbeatHandler(MassTransitConnectorHeartbeatStatus connectorHeartbeatStatus) : IHandleMessages { public Task Handle(MassTransitConnectorHeartbeat message, IMessageHandlerContext context) diff --git a/src/ServiceControl/Notifications/Email/SendEmailNotificationHandler.cs b/src/ServiceControl/Notifications/Email/SendEmailNotificationHandler.cs index 866beb314c..5519662e4d 100644 --- a/src/ServiceControl/Notifications/Email/SendEmailNotificationHandler.cs +++ b/src/ServiceControl/Notifications/Email/SendEmailNotificationHandler.cs @@ -8,21 +8,10 @@ using Persistence; using ServiceBus.Management.Infrastructure.Settings; - class SendEmailNotificationHandler : IHandleMessages + [Handler] + class SendEmailNotificationHandler(IErrorMessageDataStore store, Settings settings, EmailThrottlingState throttlingState, EmailSender emailSender, ILogger logger) + : IHandleMessages { - readonly IErrorMessageDataStore store; - readonly EmailThrottlingState throttlingState; - readonly EmailSender emailSender; - - public SendEmailNotificationHandler(IErrorMessageDataStore store, Settings settings, EmailThrottlingState throttlingState, EmailSender emailSender, ILogger logger) - { - this.store = store; - this.throttlingState = throttlingState; - this.emailSender = emailSender; - this.logger = logger; - emailDropFolder = settings.EmailDropFolder; - } - public async Task Handle(SendEmailNotification message, IMessageHandlerContext context) { NotificationsSettings notifications; @@ -92,12 +81,11 @@ public async Task Handle(SendEmailNotification message, IMessageHandlerContext c } } - string emailDropFolder; + readonly string emailDropFolder = settings.EmailDropFolder; - readonly ILogger logger; - static TimeSpan spinDelay = TimeSpan.FromSeconds(1); - static TimeSpan throttlingDelay = TimeSpan.FromSeconds(30); - static TimeSpan cacheTimeout = TimeSpan.FromMinutes(5); + static readonly TimeSpan spinDelay = TimeSpan.FromSeconds(1); + static readonly TimeSpan throttlingDelay = TimeSpan.FromSeconds(30); + static readonly TimeSpan cacheTimeout = TimeSpan.FromMinutes(5); public static RecoverabilityAction RecoverabilityPolicy(RecoverabilityConfig config, ErrorContext context) { @@ -110,10 +98,5 @@ public static RecoverabilityAction RecoverabilityPolicy(RecoverabilityConfig con } } - class EmailNotificationException : Exception - { - public EmailNotificationException(Exception exception) : base("Error sending email notification.", exception) - { - } - } + class EmailNotificationException(Exception exception) : Exception("Error sending email notification.", exception); } \ No newline at end of file diff --git a/src/ServiceControl/Recoverability/Archiving/ArchiveAllInGroupHandler.cs b/src/ServiceControl/Recoverability/Archiving/ArchiveAllInGroupHandler.cs index cabaab602b..bf70107845 100644 --- a/src/ServiceControl/Recoverability/Archiving/ArchiveAllInGroupHandler.cs +++ b/src/ServiceControl/Recoverability/Archiving/ArchiveAllInGroupHandler.cs @@ -5,15 +5,9 @@ namespace ServiceControl.Recoverability using NServiceBus; using ServiceControl.Persistence.Recoverability; - class ArchiveAllInGroupHandler : IHandleMessages + [Handler] + class ArchiveAllInGroupHandler(IArchiveMessages archiver, RetryingManager retryingManager, ILogger logger) : IHandleMessages { - public ArchiveAllInGroupHandler(IArchiveMessages archiver, RetryingManager retryingManager, ILogger logger) - { - this.archiver = archiver; - this.retryingManager = retryingManager; - this.logger = logger; - } - public async Task Handle(ArchiveAllInGroup message, IMessageHandlerContext context) { if (retryingManager.IsRetryInProgressFor(message.GroupId)) @@ -24,9 +18,5 @@ public async Task Handle(ArchiveAllInGroup message, IMessageHandlerContext conte await archiver.ArchiveAllInGroup(message.GroupId); } - - readonly IArchiveMessages archiver; - readonly RetryingManager retryingManager; - readonly ILogger logger; } } diff --git a/src/ServiceControl/Recoverability/Archiving/UnArchiveAllInGroupHandler.cs b/src/ServiceControl/Recoverability/Archiving/UnArchiveAllInGroupHandler.cs index fd853f5f65..c84c486be1 100644 --- a/src/ServiceControl/Recoverability/Archiving/UnArchiveAllInGroupHandler.cs +++ b/src/ServiceControl/Recoverability/Archiving/UnArchiveAllInGroupHandler.cs @@ -5,15 +5,9 @@ namespace ServiceControl.Recoverability using NServiceBus; using ServiceControl.Persistence.Recoverability; - class UnarchiveAllInGroupHandler : IHandleMessages + [Handler] + class UnarchiveAllInGroupHandler(IArchiveMessages archiver, RetryingManager retryingManager, ILogger logger) : IHandleMessages { - public UnarchiveAllInGroupHandler(IArchiveMessages archiver, RetryingManager retryingManager, ILogger logger) - { - this.archiver = archiver; - this.retryingManager = retryingManager; - this.logger = logger; - } - public async Task Handle(UnarchiveAllInGroup message, IMessageHandlerContext context) { if (retryingManager.IsRetryInProgressFor(message.GroupId)) @@ -24,9 +18,5 @@ public async Task Handle(UnarchiveAllInGroup message, IMessageHandlerContext con await archiver.UnarchiveAllInGroup(message.GroupId); } - - IArchiveMessages archiver; - RetryingManager retryingManager; - readonly ILogger logger; } } \ No newline at end of file diff --git a/src/ServiceControl/Recoverability/Editing/EditHandler.cs b/src/ServiceControl/Recoverability/Editing/EditHandler.cs index 0390cd4844..92b74745a2 100644 --- a/src/ServiceControl/Recoverability/Editing/EditHandler.cs +++ b/src/ServiceControl/Recoverability/Editing/EditHandler.cs @@ -14,20 +14,10 @@ using ServiceControl.Persistence; using ServiceControl.Persistence.MessageRedirects; - class EditHandler : IHandleMessages + [Handler] + class EditHandler(IErrorMessageDataStore store, IMessageRedirectsDataStore redirectsStore, IMessageDispatcher dispatcher, ErrorQueueNameCache errorQueueNameCache, IDomainEvents domainEvents, ILogger logger) + : IHandleMessages { - public EditHandler(IErrorMessageDataStore store, IMessageRedirectsDataStore redirectsStore, IMessageDispatcher dispatcher, ErrorQueueNameCache errorQueueNameCache, IDomainEvents domainEvents, ILogger logger) - { - this.store = store; - this.redirectsStore = redirectsStore; - this.dispatcher = dispatcher; - this.errorQueueNameCache = errorQueueNameCache; - this.domainEvents = domainEvents; - this.logger = logger; - corruptedReplyToHeaderStrategy = new CorruptedReplyToHeaderStrategy(RuntimeEnvironment.MachineName, logger); - - } - public async Task Handle(EditAndSend message, IMessageHandlerContext context) { FailedMessage failedMessage; @@ -125,12 +115,6 @@ Task DispatchEditedMessage(OutgoingMessage editedMessage, string address, IMessa context.CancellationToken); } - readonly CorruptedReplyToHeaderStrategy corruptedReplyToHeaderStrategy; - readonly IErrorMessageDataStore store; - readonly IMessageRedirectsDataStore redirectsStore; - readonly IMessageDispatcher dispatcher; - readonly ErrorQueueNameCache errorQueueNameCache; - readonly ILogger logger; - readonly IDomainEvents domainEvents; + readonly CorruptedReplyToHeaderStrategy corruptedReplyToHeaderStrategy = new(RuntimeEnvironment.MachineName, logger); } } \ No newline at end of file diff --git a/src/ServiceControl/Recoverability/Retrying/Handlers/PendingRetriesHandler.cs b/src/ServiceControl/Recoverability/Retrying/Handlers/PendingRetriesHandler.cs index 8cff935258..62cde7fe7f 100644 --- a/src/ServiceControl/Recoverability/Retrying/Handlers/PendingRetriesHandler.cs +++ b/src/ServiceControl/Recoverability/Retrying/Handlers/PendingRetriesHandler.cs @@ -6,6 +6,7 @@ namespace ServiceControl.Recoverability using NServiceBus; using Persistence; + [Handler] class PendingRetriesHandler : IHandleMessages, IHandleMessages { diff --git a/src/ServiceControl/Recoverability/Retrying/Handlers/RetriesHandler.cs b/src/ServiceControl/Recoverability/Retrying/Handlers/RetriesHandler.cs index 00a0c46bfc..4a2e7266c5 100644 --- a/src/ServiceControl/Recoverability/Retrying/Handlers/RetriesHandler.cs +++ b/src/ServiceControl/Recoverability/Retrying/Handlers/RetriesHandler.cs @@ -6,21 +6,13 @@ namespace ServiceControl.Recoverability using NServiceBus; using ServiceControl.Persistence; - class RetriesHandler : IHandleMessages, + [Handler] + class RetriesHandler(RetriesGateway retries, IErrorMessageDataStore dataStore) : IHandleMessages, IHandleMessages, IHandleMessages, IHandleMessages, IHandleMessages { - readonly RetriesGateway retries; - readonly IErrorMessageDataStore dataStore; - - public RetriesHandler(RetriesGateway retries, IErrorMessageDataStore dataStore) - { - this.retries = retries; - this.dataStore = dataStore; - } - /// /// For handling leftover messages. MessageFailed are no longer published on the bus and the code is moved to /// . @@ -49,15 +41,9 @@ public Task Handle(RequestRetryAll message, IMessageHandlerContext context) return Task.CompletedTask; } - public Task Handle(RetryMessage message, IMessageHandlerContext context) - { - return retries.StartRetryForSingleMessage(message.FailedMessageId); - } + public Task Handle(RetryMessage message, IMessageHandlerContext context) => retries.StartRetryForSingleMessage(message.FailedMessageId); - public Task Handle(RetryMessagesById message, IMessageHandlerContext context) - { - return retries.StartRetryForMessageSelection(message.MessageUniqueIds); - } + public Task Handle(RetryMessagesById message, IMessageHandlerContext context) => retries.StartRetryForMessageSelection(message.MessageUniqueIds); public Task Handle(RetryMessagesByQueueAddress message, IMessageHandlerContext context) { diff --git a/src/ServiceControl/Recoverability/Retrying/Handlers/RetryAllInGroupHandler.cs b/src/ServiceControl/Recoverability/Retrying/Handlers/RetryAllInGroupHandler.cs index 8f17182f23..97271902fd 100644 --- a/src/ServiceControl/Recoverability/Retrying/Handlers/RetryAllInGroupHandler.cs +++ b/src/ServiceControl/Recoverability/Retrying/Handlers/RetryAllInGroupHandler.cs @@ -7,7 +7,9 @@ namespace ServiceControl.Recoverability using ServiceControl.Persistence; using ServiceControl.Persistence.Recoverability; - class RetryAllInGroupHandler : IHandleMessages + [Handler] + class RetryAllInGroupHandler(RetriesGateway retries, RetryingManager retryingManager, IArchiveMessages archiver, IRetryDocumentDataStore dataStore, ILogger logger) + : IHandleMessages { public async Task Handle(RetryAllInGroup message, IMessageHandlerContext context) { @@ -42,20 +44,5 @@ public async Task Handle(RetryAllInGroup message, IMessageHandlerContext context started )); } - - public RetryAllInGroupHandler(RetriesGateway retries, RetryingManager retryingManager, IArchiveMessages archiver, IRetryDocumentDataStore dataStore, ILogger logger) - { - this.retries = retries; - this.retryingManager = retryingManager; - this.archiver = archiver; - this.dataStore = dataStore; - this.logger = logger; - } - - readonly RetriesGateway retries; - readonly RetryingManager retryingManager; - readonly IArchiveMessages archiver; - readonly IRetryDocumentDataStore dataStore; - readonly ILogger logger; } } \ No newline at end of file diff --git a/src/ServiceControl/Recoverability/Retrying/Handlers/RetryHandlerForBackwardsCompatability.cs b/src/ServiceControl/Recoverability/Retrying/Handlers/RetryHandlerForBackwardsCompatability.cs index 673c120238..43e8a438d9 100644 --- a/src/ServiceControl/Recoverability/Retrying/Handlers/RetryHandlerForBackwardsCompatability.cs +++ b/src/ServiceControl/Recoverability/Retrying/Handlers/RetryHandlerForBackwardsCompatability.cs @@ -7,17 +7,13 @@ namespace ServiceControl.Recoverability // This Handler only exists for messages which are in transit when SC is upgraded to use the new Retries facility // Once these messages have been cleared out it is no longer required + [Handler] class RetryHandlerForBackwardsCompatability : IHandleMessages, IHandleMessages { - public Task Handle(PerformRetry message, IMessageHandlerContext context) - { - return context.SendLocal(m => - m.MessageUniqueIds = new[] { message.FailedMessageId }); - } + public Task Handle(PerformRetry message, IMessageHandlerContext context) => + context.SendLocal(m => + m.MessageUniqueIds = [message.FailedMessageId]); - public Task Handle(RegisterSuccessfulRetry message, IMessageHandlerContext context) - { - return context.SendLocal(m => { m.FailedMessageId = message.FailedMessageId; }); - } + public Task Handle(RegisterSuccessfulRetry message, IMessageHandlerContext context) => context.SendLocal(m => { m.FailedMessageId = message.FailedMessageId; }); } } \ No newline at end of file diff --git a/src/ServiceControl/SagaAudit/SagaUpdatedHandler.cs b/src/ServiceControl/SagaAudit/SagaUpdatedHandler.cs index 48c1b97536..6ddbafa10f 100644 --- a/src/ServiceControl/SagaAudit/SagaUpdatedHandler.cs +++ b/src/ServiceControl/SagaAudit/SagaUpdatedHandler.cs @@ -10,6 +10,7 @@ using ServiceControl.Connection; using ServiceControl.Infrastructure; + [Handler] class SagaUpdatedHandler(IPlatformConnectionBuilder connectionBuilder, ILogger logger) : IHandleMessages { From 54a6a787f1eb691a2414092bf7325ea1cf2b73a4 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 11:16:35 +0200 Subject: [PATCH 12/19] Refactor InternalCustomChecks to use collection initialization syntax --- .../InternalCustomChecks/InternalCustomChecks.cs | 2 +- .../InternalCustomChecksHostedService.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ServiceControl/CustomChecks/InternalCustomChecks/InternalCustomChecks.cs b/src/ServiceControl/CustomChecks/InternalCustomChecks/InternalCustomChecks.cs index cc840c6e76..a34b41a62e 100644 --- a/src/ServiceControl/CustomChecks/InternalCustomChecks/InternalCustomChecks.cs +++ b/src/ServiceControl/CustomChecks/InternalCustomChecks/InternalCustomChecks.cs @@ -21,7 +21,7 @@ public static IHostApplicationBuilder AddInternalCustomChecks(this IHostApplicat services.AddCustomCheck(); services.AddHostedService(provider => new InternalCustomChecksHostedService( - provider.GetServices().ToList(), + [.. provider.GetServices()], provider.GetRequiredService(), provider.GetRequiredService(), provider.GetRequiredService(), diff --git a/src/ServiceControl/CustomChecks/InternalCustomChecks/InternalCustomChecksHostedService.cs b/src/ServiceControl/CustomChecks/InternalCustomChecks/InternalCustomChecksHostedService.cs index b75804e2d1..8e4570999c 100644 --- a/src/ServiceControl/CustomChecks/InternalCustomChecks/InternalCustomChecksHostedService.cs +++ b/src/ServiceControl/CustomChecks/InternalCustomChecks/InternalCustomChecksHostedService.cs @@ -37,7 +37,7 @@ public async Task StopAsync(CancellationToken cancellationToken) { if (managers.Any()) { - await Task.WhenAll(managers.Select(m => m.Stop()).ToArray()); + await Task.WhenAll([.. managers.Select(m => m.Stop())]); } } @@ -47,6 +47,7 @@ public async Task StopAsync(CancellationToken cancellationToken) HostId = hostInfo.HostId, Name = endpointName }; - IList managers = []; + + readonly IList managers = []; } } \ No newline at end of file From 7daea2bd2b0dab7917ac5495452dc167c3576b55 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 11:22:27 +0200 Subject: [PATCH 13/19] Remove assembly exclusion logic from endpoint configuration --- .../EndpointConfigurationExtensions.cs | 4 ---- .../EndpointConfigurationExtensions.cs | 4 ---- .../Hosting/Commands/RunCommand.cs | 2 +- .../Infrastructure/NServiceBusFactory.cs | 2 +- .../EndpointConfigurationExtensions.cs | 4 ---- .../ServiceControlComponentRunner.cs | 22 ------------------- .../Commands/ImportFailedErrorsCommand.cs | 2 +- .../Hosting/Commands/RunCommand.cs | 2 +- .../Infrastructure/NServiceBusFactory.cs | 2 +- 9 files changed, 5 insertions(+), 39 deletions(-) diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index cccc219a39..e0eddeff89 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -1,6 +1,5 @@ namespace ServiceControl.AcceptanceTests.TestSupport { - using System.IO; using AcceptanceTesting; using NServiceBus; using NServiceBus.AcceptanceTesting; @@ -23,9 +22,6 @@ public static void CustomizeServiceControlEndpointTesting(this EndpointConfigura configuration.Pipeline.Register(); configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); - - var assemblyScanner = configuration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies(Path.GetFileName(typeof(ServiceControlComponentRunner).Assembly.Location)); } } } \ No newline at end of file diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index 4b4ba5e2f8..990ae38d63 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -1,6 +1,5 @@ namespace ServiceControl.Audit.AcceptanceTests.TestSupport; -using System.IO; using AcceptanceTesting; using NServiceBus; using NServiceBus.AcceptanceTesting; @@ -18,8 +17,5 @@ public static void CustomizeServiceControlAuditEndpointTesting(this EndpointConf configuration.Pipeline.Register(); configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); - - var assemblyScanner = configuration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies(Path.GetFileName(typeof(ServiceControlComponentRunner).Assembly.Location)); } } \ No newline at end of file diff --git a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/RunCommand.cs b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/RunCommand.cs index 22e2fff776..5bf0db7b5c 100644 --- a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/RunCommand.cs +++ b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/RunCommand.cs @@ -14,7 +14,7 @@ public override async Task Execute(HostArguments args, Settings settings) { var endpointConfiguration = new EndpointConfiguration(settings.InstanceName); var assemblyScanner = endpointConfiguration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies("ServiceControl.Plugin"); + assemblyScanner.Disable = true; var hostBuilder = WebApplication.CreateBuilder(); diff --git a/src/ServiceControl.Audit/Infrastructure/NServiceBusFactory.cs b/src/ServiceControl.Audit/Infrastructure/NServiceBusFactory.cs index a6cd60b3de..bb8f302f22 100644 --- a/src/ServiceControl.Audit/Infrastructure/NServiceBusFactory.cs +++ b/src/ServiceControl.Audit/Infrastructure/NServiceBusFactory.cs @@ -23,7 +23,7 @@ public static void Configure(Settings.Settings settings, ITransportCustomization { configuration = new EndpointConfiguration(endpointName); var assemblyScanner = configuration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies("ServiceControl.Plugin"); + assemblyScanner.Disable = true; } configuration.EnableFeature(); diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index cc90a8fb60..68d9b4e274 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -1,6 +1,5 @@ namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport; -using System.IO; using AcceptanceTesting; using NServiceBus; using NServiceBus.AcceptanceTesting; @@ -18,8 +17,5 @@ public static void CustomizeServiceControlMonitoringEndpointTesting(this Endpoin configuration.Pipeline.Register(); configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); - - var assemblyScanner = configuration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies(Path.GetFileName(typeof(ServiceControlComponentRunner).Assembly.Location)); } } \ No newline at end of file diff --git a/src/ServiceControl.MultiInstance.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.MultiInstance.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index 231c462e66..4bd8b97ed4 100644 --- a/src/ServiceControl.MultiInstance.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.MultiInstance.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -65,17 +65,6 @@ public async Task Initialize(RunDescriptor run) SettingsPerInstance[AuditInstanceSettings.DEFAULT_INSTANCE_NAME] = auditSettings; }, auditEndpointConfiguration => { - var scanner = auditEndpointConfiguration.AssemblyScanner(); - var excludedAssemblies = new[] - { - "ServiceControl.Persistence.RavenDB.dll", - "ServiceControl.AcceptanceTests.RavenDB.dll", - "ServiceControl.Audit.AcceptanceTests.dll", - Path.GetFileName(typeof(PrimaryInstanceSettings).Assembly.Location), - Path.GetFileName(typeof(ServiceControlComponentRunner).Assembly.Location), - }; - scanner.ExcludeAssemblies(excludedAssemblies); - customAuditEndpointConfiguration(auditEndpointConfiguration); }, _ => { }, @@ -98,17 +87,6 @@ public async Task Initialize(RunDescriptor run) }, primaryEndpointConfiguration => { - var scanner = primaryEndpointConfiguration.AssemblyScanner(); - var excludedAssemblies = new[] - { - "ServiceControl.Persistence.RavenDB.dll", - "ServiceControl.AcceptanceTests.RavenDB.dll", - "ServiceControl.Audit.AcceptanceTests.dll", - Path.GetFileName(typeof(AuditInstanceSettings).Assembly.Location), - typeof(ServiceControlComponentRunner).Assembly.GetName().Name - }; - scanner.ExcludeAssemblies(excludedAssemblies); - customPrimaryEndpointConfiguration(primaryEndpointConfiguration); }, primaryHostBuilder => diff --git a/src/ServiceControl/Hosting/Commands/ImportFailedErrorsCommand.cs b/src/ServiceControl/Hosting/Commands/ImportFailedErrorsCommand.cs index 105f756daf..a1bb65c89d 100644 --- a/src/ServiceControl/Hosting/Commands/ImportFailedErrorsCommand.cs +++ b/src/ServiceControl/Hosting/Commands/ImportFailedErrorsCommand.cs @@ -54,7 +54,7 @@ protected virtual EndpointConfiguration CreateEndpointConfiguration(Settings set { var endpointConfiguration = new EndpointConfiguration(settings.InstanceName); var assemblyScanner = endpointConfiguration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies("ServiceControl.Plugin"); + assemblyScanner.Disable = true; return endpointConfiguration; } diff --git a/src/ServiceControl/Hosting/Commands/RunCommand.cs b/src/ServiceControl/Hosting/Commands/RunCommand.cs index ebc08958cf..e694fb4acb 100644 --- a/src/ServiceControl/Hosting/Commands/RunCommand.cs +++ b/src/ServiceControl/Hosting/Commands/RunCommand.cs @@ -18,7 +18,7 @@ public override async Task Execute(HostArguments args, Settings settings) { var endpointConfiguration = new EndpointConfiguration(settings.InstanceName); var assemblyScanner = endpointConfiguration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies("ServiceControl.Plugin"); + assemblyScanner.Disable = true; settings.RunCleanupBundle = true; diff --git a/src/ServiceControl/Infrastructure/NServiceBusFactory.cs b/src/ServiceControl/Infrastructure/NServiceBusFactory.cs index 8818076cff..1b076faf9c 100644 --- a/src/ServiceControl/Infrastructure/NServiceBusFactory.cs +++ b/src/ServiceControl/Infrastructure/NServiceBusFactory.cs @@ -26,7 +26,7 @@ public static void Configure(Settings.Settings settings, ITransportCustomization { configuration = new EndpointConfiguration(transportSettings.EndpointName); var assemblyScanner = configuration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies("ServiceControl.Plugin"); + assemblyScanner.Disable = true; } configuration.EnableFeature(); From 51c352625ec5fac57587189219968018f7d96eed Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 11:29:53 +0200 Subject: [PATCH 14/19] Register handlers --- .../HostApplicationBuilderExtensions.cs | 2 ++ src/ServiceControl/Infrastructure/NServiceBusFactory.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs index b55672e51d..2478e88545 100644 --- a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs @@ -81,6 +81,8 @@ public static void AddServiceControlMonitoring(this IHostApplicationBuilder host static void ConfigureEndpoint(EndpointConfiguration config, Func onCriticalError, ITransportCustomization transportCustomization, TransportSettings transportSettings, Settings settings, IServiceCollection services) { + config.Handlers.ServiceControlMonitoringAssembly.AddAll(); + transportCustomization.CustomizeMonitoringEndpoint(config, transportSettings); var serviceControlThroughputDataQueue = settings.ServiceControlThroughputDataQueue; diff --git a/src/ServiceControl/Infrastructure/NServiceBusFactory.cs b/src/ServiceControl/Infrastructure/NServiceBusFactory.cs index 1b076faf9c..a9238b6043 100644 --- a/src/ServiceControl/Infrastructure/NServiceBusFactory.cs +++ b/src/ServiceControl/Infrastructure/NServiceBusFactory.cs @@ -29,6 +29,8 @@ public static void Configure(Settings.Settings settings, ITransportCustomization assemblyScanner.Disable = true; } + configuration.Handlers.ServiceControlAssembly.AddAll(); + configuration.EnableFeature(); configuration.GetSettings().Set("ServiceControl.Settings", settings); From d1a27b5a271f557dd7e0f0707ab5ec2136f16097 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 11:31:28 +0200 Subject: [PATCH 15/19] Disable assembly scanner in monitoring too --- .../HostApplicationBuilderExtensions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs index 2478e88545..4e4e1a929a 100644 --- a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs @@ -81,6 +81,8 @@ public static void AddServiceControlMonitoring(this IHostApplicationBuilder host static void ConfigureEndpoint(EndpointConfiguration config, Func onCriticalError, ITransportCustomization transportCustomization, TransportSettings transportSettings, Settings settings, IServiceCollection services) { + config.AssemblyScanner().Disable = true; + config.Handlers.ServiceControlMonitoringAssembly.AddAll(); transportCustomization.CustomizeMonitoringEndpoint(config, transportSettings); From 3b46217d31c246d59c35ff03e0aa71f66afc9abf Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 11:51:45 +0200 Subject: [PATCH 16/19] Customization extensions also need to disable assembly scanner --- .../TestSupport/EndpointConfigurationExtensions.cs | 2 ++ .../TestSupport/EndpointConfigurationExtensions.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index e0eddeff89..f10878310d 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -22,6 +22,8 @@ public static void CustomizeServiceControlEndpointTesting(this EndpointConfigura configuration.Pipeline.Register(); configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); + + configuration.AssemblyScanner().Disable = true; } } } \ No newline at end of file diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index 990ae38d63..22e514e43f 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -17,5 +17,7 @@ public static void CustomizeServiceControlAuditEndpointTesting(this EndpointConf configuration.Pipeline.Register(); configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); + + configuration.AssemblyScanner().Disable = true; } } \ No newline at end of file From 67f3e06f09a37af40d3439a0204e75724b7da942 Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 15:49:15 +0200 Subject: [PATCH 17/19] Get rid off NServiceBus.Extensions.Hosting dependency --- src/Directory.Packages.props | 1 - .../NServiceBusAcceptanceTest.cs | 6 +----- .../HostApplicationBuilderExtensions.cs | 2 +- src/ServiceControl.Audit/ServiceControl.Audit.csproj | 1 - .../HostApplicationBuilderExtensions.cs | 2 +- .../ServiceControl.Monitoring.csproj | 1 - src/ServiceControl/HostApplicationBuilderExtensions.cs | 2 +- src/ServiceControl/ServiceControl.csproj | 1 - 8 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 715e512064..3e01ba102b 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -38,7 +38,6 @@ - diff --git a/src/ServiceControl.AcceptanceTesting/NServiceBusAcceptanceTest.cs b/src/ServiceControl.AcceptanceTesting/NServiceBusAcceptanceTest.cs index 21fe3d4287..79cda757ca 100644 --- a/src/ServiceControl.AcceptanceTesting/NServiceBusAcceptanceTest.cs +++ b/src/ServiceControl.AcceptanceTesting/NServiceBusAcceptanceTest.cs @@ -17,10 +17,7 @@ public abstract partial class NServiceBusAcceptanceTest { [SetUp] - public void SetUp() - { - LogManager.Use(); // Ensures that every test the log manager is 'reset' as log manager can otherwise point to disposed resources. For example, when a test uses NServiceBus hosting - + public void SetUp() => Conventions.EndpointNamingConvention = t => { var classAndEndpoint = t.FullName.Split('.').Last(); @@ -37,7 +34,6 @@ public void SetUp() return testName + "." + endpointBuilder; }; - } [TearDown] public void TearDown() diff --git a/src/ServiceControl.Audit/HostApplicationBuilderExtensions.cs b/src/ServiceControl.Audit/HostApplicationBuilderExtensions.cs index d65a66697f..14db651ece 100644 --- a/src/ServiceControl.Audit/HostApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Audit/HostApplicationBuilderExtensions.cs @@ -68,7 +68,7 @@ public static void AddServiceControlAudit(this IHostApplicationBuilder builder, services.AddPersistence(persistenceSettings, persistenceConfiguration); NServiceBusFactory.Configure(settings, transportCustomization, transportSettings, onCriticalError, configuration); - builder.UseNServiceBus(configuration); + services.AddNServiceBusEndpoint(configuration); builder.AddMetrics(settings); diff --git a/src/ServiceControl.Audit/ServiceControl.Audit.csproj b/src/ServiceControl.Audit/ServiceControl.Audit.csproj index 1752bf81bd..c8374391f7 100644 --- a/src/ServiceControl.Audit/ServiceControl.Audit.csproj +++ b/src/ServiceControl.Audit/ServiceControl.Audit.csproj @@ -27,7 +27,6 @@ - diff --git a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs index 4e4e1a929a..4b8a9fd90a 100644 --- a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs @@ -74,7 +74,7 @@ public static void AddServiceControlMonitoring(this IHostApplicationBuilder host services.AddLicenseCheck(); ConfigureEndpoint(endpointConfiguration, onCriticalError, transportCustomization, transportSettings, settings, services); - hostBuilder.UseNServiceBus(endpointConfiguration); + services.AddNServiceBusEndpoint(endpointConfiguration); hostBuilder.AddAsyncTimer(); } diff --git a/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj b/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj index 566d603e07..4ba3b8d29d 100644 --- a/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj +++ b/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj @@ -23,7 +23,6 @@ - diff --git a/src/ServiceControl/HostApplicationBuilderExtensions.cs b/src/ServiceControl/HostApplicationBuilderExtensions.cs index fcb607f61a..f7e4f569c7 100644 --- a/src/ServiceControl/HostApplicationBuilderExtensions.cs +++ b/src/ServiceControl/HostApplicationBuilderExtensions.cs @@ -85,7 +85,7 @@ public static void AddServiceControl(this IHostApplicationBuilder hostBuilder, S services.AddMetrics(settings.PrintMetrics); NServiceBusFactory.Configure(settings, transportCustomization, transportSettings, configuration); - hostBuilder.UseNServiceBus(configuration); + hostBuilder.Services.AddNServiceBusEndpoint(configuration); hostBuilder.AddServicePulseSignalRNotifier(); hostBuilder.AddEmailNotifications(); diff --git a/src/ServiceControl/ServiceControl.csproj b/src/ServiceControl/ServiceControl.csproj index d931751d34..93a9508eaa 100644 --- a/src/ServiceControl/ServiceControl.csproj +++ b/src/ServiceControl/ServiceControl.csproj @@ -34,7 +34,6 @@ - From 526286d81a01ac67fdb22a092a3382a467cfe2fc Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 16:05:31 +0200 Subject: [PATCH 18/19] Get rid of the custom context appender since Core acceptance tests does all that already --- .../TestSupport/ContextLoggerExtensions.cs | 111 ------------------ .../WebApplicationBuilderExtensions.cs | 1 - 2 files changed, 112 deletions(-) delete mode 100644 src/ServiceControl.AcceptanceTests/TestSupport/ContextLoggerExtensions.cs diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/ContextLoggerExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/ContextLoggerExtensions.cs deleted file mode 100644 index cd01c38d96..0000000000 --- a/src/ServiceControl.AcceptanceTests/TestSupport/ContextLoggerExtensions.cs +++ /dev/null @@ -1,111 +0,0 @@ -namespace ServiceControl.AcceptanceTests -{ - using System; - using System.Collections.Concurrent; - using System.Reflection; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.DependencyInjection.Extensions; - using Microsoft.Extensions.Logging; - using NServiceBus.AcceptanceTesting; - - static class ContextLoggerExtensions - { - public static ILoggingBuilder AddScenarioContextLogging(this ILoggingBuilder builder) - { - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); - return builder; - } - - class ContextLoggerProvider : ILoggerProvider - { - readonly ConcurrentDictionary loggers = new ConcurrentDictionary(); - - public void Dispose() => loggers.Clear(); - - public ILogger CreateLogger(string categoryName) - { - try - { - return loggers.GetOrAdd(categoryName, name => new ContextLogger(name)); - } - catch (Exception e) - { - Console.WriteLine($"#### Fail to get logger. Exception: {e}"); - throw; - } - } - } - - class ContextLogger : ILogger - { - readonly string categoryName; - - public ContextLogger(string categoryName) - { - this.categoryName = categoryName; - } - - ScenarioContext GetContext() - { - var propertyInfo = typeof(ScenarioContext).GetProperty("Current", BindingFlags.NonPublic | BindingFlags.Static); - - return (ScenarioContext)propertyInfo.GetValue(null); - } - - public void Log(LogLevel logLevel, EventId eventId, TState state, - Exception exception, Func formatter) - - { - try - { - GetContext().Logs.Enqueue(new ScenarioContext.LogItem - { - LoggerName = categoryName, - Message = $"{state}" + (exception == null ? string.Empty : $"\n{exception}"), //HINT: default Microsoft formatter will ignore the exception - Level = ConvertLogLevel(logLevel) - }); - } - catch (Exception e) - { - Console.WriteLine($"#### Fail to log message. Exception: {e}"); - } - } - - NServiceBus.Logging.LogLevel ConvertLogLevel(LogLevel level) - => level switch - { - LogLevel.Critical => NServiceBus.Logging.LogLevel.Fatal, - LogLevel.Trace => NServiceBus.Logging.LogLevel.Debug, - LogLevel.Debug => NServiceBus.Logging.LogLevel.Debug, - LogLevel.Information => NServiceBus.Logging.LogLevel.Info, - LogLevel.Warning => NServiceBus.Logging.LogLevel.Warn, - LogLevel.Error => NServiceBus.Logging.LogLevel.Error, - LogLevel.None => NServiceBus.Logging.LogLevel.Debug, - _ => throw new ArgumentOutOfRangeException(nameof(level), level, null) - }; - - public bool IsEnabled(LogLevel logLevel) - { - try - { - return ConvertLogLevel(logLevel) >= GetContext()?.LogLevel; - } - catch (Exception e) - { - Console.WriteLine($"#### Fail to log message. Exception: {e}"); - } - - return false; - } - - public IDisposable BeginScope(TState state) => NullScope.Instance; - - class NullScope : IDisposable - { - public void Dispose() { } - - public static NullScope Instance { get; } = new NullScope(); - } - } - } -} \ No newline at end of file diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs index 3e7b59add5..7c5aa29a1b 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs @@ -13,7 +13,6 @@ public static void AddServiceControlTesting(this WebApplicationBuilder hostBuild { // Do not register additional test controllers or hosted services here. Instead, in the test that needs them, use (for example): // CustomizeHostBuilder = builder => builder.ConfigureServices((hostContext, services) => services.AddHostedService()); - hostBuilder.Logging.AddScenarioContextLogging(); hostBuilder.WebHost.UseTestServer(options => options.BaseAddress = new Uri(settings.RootUrl)); From c7e63e5d30171f72b28b8cd08e5db9e90c0c0dec Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Mon, 11 May 2026 17:36:00 +0200 Subject: [PATCH 19/19] Update NServiceBus packages to version 10.2.0-alpha.10 --- src/Directory.Packages.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 3e01ba102b..3963d95929 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -34,8 +34,8 @@ - - + +