From 9ee427e8a89c4123eb86c90ee6bbd576870bc5f9 Mon Sep 17 00:00:00 2001 From: maliming Date: Sat, 2 May 2026 14:15:52 +0800 Subject: [PATCH] Disable conventional registration of InMemoryDynamicBackgroundWorker InMemoryDynamicBackgroundWorker indirectly implements ISingletonDependency via IBackgroundWorker, so conventional registration tries to register it as a service. Its constructor takes a string workerName parameter that the DI container cannot resolve, which crashes any host that runs ServiceCollection validation (e.g. ASP.NET Core in Development, where WebApplicationBuilder.Build() enables ValidateOnBuild). The dynamic worker is created on demand by DefaultDynamicBackgroundWorkerManager and must not be auto-registered, so mark it with [DisableConventionalRegistration]. --- .../InMemoryDynamicBackgroundWorker.cs | 2 ++ ...amicBackgroundWorker_Registration_Tests.cs | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/InMemoryDynamicBackgroundWorker_Registration_Tests.cs diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/InMemoryDynamicBackgroundWorker.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/InMemoryDynamicBackgroundWorker.cs index bab468a655..7bffb3895a 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/InMemoryDynamicBackgroundWorker.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/InMemoryDynamicBackgroundWorker.cs @@ -1,10 +1,12 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; using Volo.Abp.Threading; namespace Volo.Abp.BackgroundWorkers; +[DisableConventionalRegistration] public class InMemoryDynamicBackgroundWorker : AsyncPeriodicBackgroundWorkerBase { public string WorkerName { get; } diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/InMemoryDynamicBackgroundWorker_Registration_Tests.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/InMemoryDynamicBackgroundWorker_Registration_Tests.cs new file mode 100644 index 0000000000..de673886f5 --- /dev/null +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/InMemoryDynamicBackgroundWorker_Registration_Tests.cs @@ -0,0 +1,33 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Xunit; + +namespace Volo.Abp.BackgroundWorkers; + +public class InMemoryDynamicBackgroundWorker_Registration_Tests +{ + [Fact] + public async Task Should_Not_Be_Auto_Registered_To_DI_Container() + { + // Regression guard: IBackgroundWorker derives from ISingletonDependency, so without + // [DisableConventionalRegistration] the conventional registration would register + // InMemoryDynamicBackgroundWorker as a Singleton. Its constructor takes a `string + // workerName` parameter that the DI container cannot resolve, which broke any host + // running ServiceCollection validation (e.g. ASP.NET Core in Development, where + // WebApplicationBuilder.Build() enables ValidateOnBuild). + using var application = await AbpApplicationFactory.CreateAsync(); + + application.Services + .Any(d => d.ServiceType == typeof(InMemoryDynamicBackgroundWorker)) + .ShouldBeFalse( + "InMemoryDynamicBackgroundWorker is created on demand by DefaultDynamicBackgroundWorkerManager " + + "and must not be auto-registered as a service."); + + // Building a fresh provider with ValidateOnBuild = true must not throw. + await using var validatingProvider = application.Services.BuildServiceProvider( + new ServiceProviderOptions { ValidateOnBuild = true }); + validatingProvider.ShouldNotBeNull(); + } +}