From 6ccb0ad689e5011d4dd1bd3275cd8bcb0fef2752 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 9 Apr 2026 12:56:42 +0800 Subject: [PATCH 1/4] Add warning for ABP modules not in the [DependsOn] chain When a type's assembly contains an ABP module but is not part of the module dependency chain, Autofac's property injection is silently skipped. This causes LazyServiceProvider and other injected properties to remain null, leading to NullReferenceException at runtime. This change detects the misconfiguration at startup and logs a warning with the affected assembly name, module type, and a fix suggestion. --- .../AbpRegistrationBuilderExtensions.cs | 20 +++++-- .../AutofacRegistration.cs | 56 +++++++++++++++++- .../WarnForOrphanedAbpModules_Tests.cs | 58 +++++++++++++++++++ 3 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/WarnForOrphanedAbpModules_Tests.cs diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs index 1c9f4b2dd8..db910d21e0 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs @@ -20,7 +20,8 @@ public static class AbpRegistrationBuilderExtensions ServiceDescriptor serviceDescriptor, IModuleContainer moduleContainer, ServiceRegistrationActionList registrationActionList, - ServiceActivatedActionList activatedActionList) + ServiceActivatedActionList activatedActionList, + HashSet? nonModuleAssemblies = null) where TActivatorData : ReflectionActivatorData { registrationBuilder = registrationBuilder.InvokeActivatedActions(activatedActionList, serviceDescriptor); @@ -37,7 +38,7 @@ public static class AbpRegistrationBuilderExtensions return registrationBuilder; } - registrationBuilder = registrationBuilder.EnablePropertyInjection(moduleContainer, implementationType); + registrationBuilder = registrationBuilder.EnablePropertyInjection(moduleContainer, implementationType, nonModuleAssemblies); registrationBuilder = registrationBuilder.InvokeRegistrationActions(registrationActionList, serviceType, implementationType, serviceDescriptor.ServiceKey); return registrationBuilder; @@ -99,14 +100,21 @@ public static class AbpRegistrationBuilderExtensions private static IRegistrationBuilder EnablePropertyInjection( this IRegistrationBuilder registrationBuilder, IModuleContainer moduleContainer, - Type implementationType) + Type implementationType, + HashSet? nonModuleAssemblies) where TActivatorData : ReflectionActivatorData { // Enable Property Injection only for types in an assembly containing an AbpModule and without a DisablePropertyInjection attribute on class or properties. - if (moduleContainer.Modules.Any(m => m.AllAssemblies.Contains(implementationType.Assembly)) && - implementationType.GetCustomAttributes(typeof(DisablePropertyInjectionAttribute), true).IsNullOrEmpty()) + if (moduleContainer.Modules.Any(m => m.AllAssemblies.Contains(implementationType.Assembly))) { - registrationBuilder = registrationBuilder.PropertiesAutowired(new AbpPropertySelector(false)); + if (implementationType.GetCustomAttributes(typeof(DisablePropertyInjectionAttribute), true).IsNullOrEmpty()) + { + registrationBuilder = registrationBuilder.PropertiesAutowired(new AbpPropertySelector(false)); + } + } + else + { + nonModuleAssemblies?.Add(implementationType.Assembly); } return registrationBuilder; diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs index b92182db92..642681db0c 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs @@ -24,7 +24,9 @@ // OTHER DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Reflection; using Autofac.Builder; using Autofac.Core; @@ -33,7 +35,9 @@ using Autofac.Core.Activators.Delegate; using Autofac.Core.Activators.Reflection; using Autofac.Core.Resolving.Pipeline; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Volo.Abp; +using Volo.Abp.Autofac; using Volo.Abp.Modularity; namespace Autofac.Extensions.DependencyInjection; @@ -301,6 +305,10 @@ public static class AutofacRegistration var registrationActionList = services.GetRegistrationActionList(); var activatedActionList = services.GetServiceActivatedActionList(); + // Assemblies where property injection was skipped because they are not in the module chain. + // Collected in EnablePropertyInjection when a type registration's assembly is not part of any loaded module. + var nonModuleAssemblies = new HashSet(); + foreach (var descriptor in services) { var implementationType = descriptor.NormalizedImplementationType(); @@ -314,7 +322,7 @@ public static class AutofacRegistration .RegisterGeneric(implementationType) .ConfigureServiceType(descriptor) .ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons) - .ConfigureAbpConventions(descriptor, moduleContainer, registrationActionList, activatedActionList); + .ConfigureAbpConventions(descriptor, moduleContainer, registrationActionList, activatedActionList, nonModuleAssemblies); } else { @@ -322,7 +330,7 @@ public static class AutofacRegistration .RegisterType(implementationType) .ConfigureServiceType(descriptor) .ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons) - .ConfigureAbpConventions(descriptor, moduleContainer, registrationActionList, activatedActionList); + .ConfigureAbpConventions(descriptor, moduleContainer, registrationActionList, activatedActionList, nonModuleAssemblies); } continue; @@ -374,5 +382,49 @@ public static class AutofacRegistration .ConfigureLifecycle(descriptor.Lifetime, null) .ExternallyOwned(); } + + WarnForOrphanedAbpModules(services, moduleContainer, nonModuleAssemblies); + } + + private static void WarnForOrphanedAbpModules( + IServiceCollection services, + IModuleContainer moduleContainer, + HashSet nonModuleAssemblies) + { + if (nonModuleAssemblies.Count == 0) + { + return; + } + + var logger = services.GetInitLogger(); + + var loadedModuleTypes = new HashSet( + moduleContainer.Modules.Select(m => m.Type)); + + foreach (var assembly in nonModuleAssemblies) + { + Type[] types; + try + { + types = assembly.GetTypes(); + } + catch (ReflectionTypeLoadException ex) + { + types = ex.Types.Where(t => t != null).ToArray()!; + } + + foreach (var type in types) + { + if (AbpModule.IsAbpModule(type) && !loadedModuleTypes.Contains(type)) + { + logger.LogWarning( + $"Assembly '{assembly.GetName().Name}' has services registered in the DI container, " + + $"but its ABP module '{type.FullName}' is not in the [DependsOn] chain. " + + "Property injection (e.g. LazyServiceProvider) will not work for these types " + + "and may cause NullReferenceException at runtime. " + + $"Add typeof({type.Name}) to your module's [DependsOn] attribute to fix this."); + } + } + } } } diff --git a/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/WarnForOrphanedAbpModules_Tests.cs b/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/WarnForOrphanedAbpModules_Tests.cs new file mode 100644 index 0000000000..1fcf04f9aa --- /dev/null +++ b/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/WarnForOrphanedAbpModules_Tests.cs @@ -0,0 +1,58 @@ +using System; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Shouldly; +using Volo.Abp.Logging; +using Volo.Abp.Modularity; +using Volo.Abp.Testing; +using Xunit; + +namespace Volo.Abp.Autofac; + +public class WarnForOrphanedAbpModules_Tests : AbpIntegratedTest +{ + private static readonly Type OrphanModuleType = typeof(AbpTestModule); + + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + [Fact] + public void Should_Warn_For_Orphaned_Abp_Modules() + { + var initLoggerFactory = GetRequiredService(); + var logger = initLoggerFactory.Create(); + + logger.Entries + .Where(e => e.LogLevel == LogLevel.Warning) + .ShouldContain(e => e.Message.Contains(OrphanModuleType.FullName!), + $"Expected a warning for orphaned module '{OrphanModuleType.FullName}'."); + } + + [Fact] + public void Should_Not_Warn_For_Loaded_Modules() + { + var initLoggerFactory = GetRequiredService(); + var logger = initLoggerFactory.Create(); + + // AbpAutofacModule IS in the DependsOn chain, so it should NOT trigger a warning. + logger.Entries + .Where(e => e.LogLevel == LogLevel.Warning) + .ShouldNotContain(e => e.Message.Contains(typeof(AbpAutofacModule).FullName!), + "Modules in the [DependsOn] chain should not be reported as orphaned."); + } + + [DependsOn(typeof(AbpAutofacModule))] + public class TestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + // Simulate ASP.NET Core's AddControllersAsServices() registering a type + // from an assembly whose ABP module is NOT in the [DependsOn] chain. + // AbpTestModule lives in the Volo.Abp.Core.Tests assembly which is not depended on. + context.Services.AddTransient(); + } + } +} From 36691ec106b9304cdc059bdd5c8df00048a8da2d Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 9 Apr 2026 14:13:36 +0800 Subject: [PATCH 2/4] Refactor logging mechanism and enhance orphan module warning tests --- .../AutofacRegistration.cs | 15 +++++++++--- .../Volo/Abp/AbpApplicationBase.cs | 11 +++++---- .../Volo/Abp/Logging/AbpInitLogEntry.cs | 2 ++ .../Volo/Abp/Logging/DefaultInitLogger.cs | 1 + .../Abp/Logging/DefaultInitLoggerFactory.cs | 22 ++++++++++++++++- .../Volo/Abp/Logging/IInitLoggerFactory.cs | 8 ++++++- .../WarnForOrphanedAbpModules_Tests.cs | 24 +++++++++++-------- 7 files changed, 63 insertions(+), 20 deletions(-) diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs index 642681db0c..f194e18775 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs @@ -396,21 +396,30 @@ public static class AutofacRegistration return; } - var logger = services.GetInitLogger(); + var logger = services.GetInitLogger(); var loadedModuleTypes = new HashSet( moduleContainer.Modules.Select(m => m.Type)); + // Only assemblies that directly reference Volo.Abp.Core can contain AbpModule subclasses. + // This skips framework/third-party assemblies (Microsoft.Extensions.*, etc.) cheaply. + var abpCoreAssemblyName = typeof(AbpModule).Assembly.GetName().Name; + foreach (var assembly in nonModuleAssemblies) { + if (!assembly.GetReferencedAssemblies().Any(r => r.Name == abpCoreAssemblyName)) + { + continue; + } + Type[] types; try { types = assembly.GetTypes(); } - catch (ReflectionTypeLoadException ex) + catch (Exception) { - types = ex.Types.Where(t => t != null).ToArray()!; + continue; } foreach (var type in types) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index 4ec967ed01..f91d251d2d 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -128,20 +128,21 @@ public abstract class AbpApplicationBase : IAbpApplication protected virtual void WriteInitLogs(IServiceProvider serviceProvider) { - var logger = serviceProvider.GetService>(); - if (logger == null) + var loggerFactory = serviceProvider.GetService(); + if (loggerFactory == null) { return; } - var initLogger = serviceProvider.GetRequiredService().Create(); + var initLoggerFactory = serviceProvider.GetRequiredService(); - foreach (var entry in initLogger.Entries) + foreach (var entry in initLoggerFactory.GetAllEntries()) { + var logger = loggerFactory.CreateLogger(entry.CategoryName); logger.Log(entry.LogLevel, entry.EventId, entry.State, entry.Exception, entry.Formatter); } - initLogger.Entries.Clear(); + initLoggerFactory.ClearAllEntries(); } protected virtual IReadOnlyList LoadModules(IServiceCollection services, AbpApplicationCreationOptions options) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs index ea17388b9f..05924395d6 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/AbpInitLogEntry.cs @@ -5,6 +5,8 @@ namespace Volo.Abp.Logging; public class AbpInitLogEntry { + public string CategoryName { get; set; } = default!; + public LogLevel LogLevel { get; set; } public EventId EventId { get; set; } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs index 98264aab74..9dcfb9dad6 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLogger.cs @@ -17,6 +17,7 @@ public class DefaultInitLogger : IInitLogger { Entries.Add(new AbpInitLogEntry { + CategoryName = typeof(T).FullName!, LogLevel = logLevel, EventId = eventId, State = state!, diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLoggerFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLoggerFactory.cs index 638888493d..aa52ed491f 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLoggerFactory.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/DefaultInitLoggerFactory.cs @@ -1,14 +1,34 @@ using System; using System.Collections.Generic; +using System.Linq; namespace Volo.Abp.Logging; public class DefaultInitLoggerFactory : IInitLoggerFactory { private readonly Dictionary _cache = []; + private readonly List> _entryLists = []; public virtual IInitLogger Create() { - return (IInitLogger)_cache.GetOrAdd(typeof(T), () => new DefaultInitLogger()); + return (IInitLogger)_cache.GetOrAdd(typeof(T), () => + { + var logger = new DefaultInitLogger(); + _entryLists.Add(logger.Entries); + return logger; + }); + } + + public virtual List GetAllEntries() + { + return _entryLists.SelectMany(l => l).ToList(); + } + + public virtual void ClearAllEntries() + { + foreach (var list in _entryLists) + { + list.Clear(); + } } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLoggerFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLoggerFactory.cs index 611e9d7477..1f06aadc86 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLoggerFactory.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Logging/IInitLoggerFactory.cs @@ -1,6 +1,12 @@ -namespace Volo.Abp.Logging; +using System.Collections.Generic; + +namespace Volo.Abp.Logging; public interface IInitLoggerFactory { IInitLogger Create(); + + List GetAllEntries(); + + void ClearAllEntries(); } diff --git a/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/WarnForOrphanedAbpModules_Tests.cs b/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/WarnForOrphanedAbpModules_Tests.cs index 1fcf04f9aa..efd1a193e6 100644 --- a/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/WarnForOrphanedAbpModules_Tests.cs +++ b/framework/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/WarnForOrphanedAbpModules_Tests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -13,19 +14,27 @@ namespace Volo.Abp.Autofac; public class WarnForOrphanedAbpModules_Tests : AbpIntegratedTest { private static readonly Type OrphanModuleType = typeof(AbpTestModule); + private List _initLogEntries = []; protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) { options.UseAutofac(); } + protected override IServiceProvider CreateServiceProvider(IServiceCollection services) + { + var serviceProvider = base.CreateServiceProvider(services); + + // Capture init log entries after Autofac Populate/Register but before WriteInitLogs clears them. + _initLogEntries = serviceProvider.GetRequiredService().GetAllEntries(); + + return serviceProvider; + } + [Fact] public void Should_Warn_For_Orphaned_Abp_Modules() { - var initLoggerFactory = GetRequiredService(); - var logger = initLoggerFactory.Create(); - - logger.Entries + _initLogEntries .Where(e => e.LogLevel == LogLevel.Warning) .ShouldContain(e => e.Message.Contains(OrphanModuleType.FullName!), $"Expected a warning for orphaned module '{OrphanModuleType.FullName}'."); @@ -34,11 +43,7 @@ public class WarnForOrphanedAbpModules_Tests : AbpIntegratedTest(); - var logger = initLoggerFactory.Create(); - - // AbpAutofacModule IS in the DependsOn chain, so it should NOT trigger a warning. - logger.Entries + _initLogEntries .Where(e => e.LogLevel == LogLevel.Warning) .ShouldNotContain(e => e.Message.Contains(typeof(AbpAutofacModule).FullName!), "Modules in the [DependsOn] chain should not be reported as orphaned."); @@ -51,7 +56,6 @@ public class WarnForOrphanedAbpModules_Tests : AbpIntegratedTest(); } } From c377fd95446b4bc74c31a5a3ce89718eb05e7ebb Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 9 Apr 2026 14:23:37 +0800 Subject: [PATCH 3/4] Refactor InitLogger to flush all categories and address review feedback - WriteInitLogs now uses ILoggerFactory to flush all InitLogger categories with their original category name instead of only flushing AbpApplicationBase - Add CategoryName to AbpInitLogEntry, recorded automatically by DefaultInitLogger using typeof(T).FullName - Add GetAllEntries/ClearAllEntries to IInitLoggerFactory interface - Add GetReferencedAssemblies filter to skip non-ABP assemblies - Handle ReflectionTypeLoadException separately from other exceptions - Add CategoryName null/empty fallback in WriteInitLogs - Skip DisablePropertyInjection types from orphaned module detection --- .../Autofac/Builder/AbpRegistrationBuilderExtensions.cs | 2 +- .../Extensions/DependencyInjection/AutofacRegistration.cs | 4 ++++ framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs index db910d21e0..2bf2d30605 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs @@ -112,7 +112,7 @@ public static class AbpRegistrationBuilderExtensions registrationBuilder = registrationBuilder.PropertiesAutowired(new AbpPropertySelector(false)); } } - else + else if (implementationType.GetCustomAttributes(typeof(DisablePropertyInjectionAttribute), true).IsNullOrEmpty()) { nonModuleAssemblies?.Add(implementationType.Assembly); } diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs index f194e18775..11216e39ec 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs @@ -417,6 +417,10 @@ public static class AutofacRegistration { types = assembly.GetTypes(); } + catch (ReflectionTypeLoadException ex) + { + types = ex.Types.Where(t => t != null).ToArray()!; + } catch (Exception) { continue; diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index f91d251d2d..6002c005b7 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -138,7 +138,10 @@ public abstract class AbpApplicationBase : IAbpApplication foreach (var entry in initLoggerFactory.GetAllEntries()) { - var logger = loggerFactory.CreateLogger(entry.CategoryName); + var categoryName = string.IsNullOrEmpty(entry.CategoryName) + ? nameof(AbpApplicationBase) + : entry.CategoryName; + var logger = loggerFactory.CreateLogger(categoryName); logger.Log(entry.LogLevel, entry.EventId, entry.State, entry.Exception, entry.Formatter); } From 040a1e7f92afced5454553411e379241875be010 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 9 Apr 2026 14:30:45 +0800 Subject: [PATCH 4/4] Extract DisablePropertyInjection check to avoid duplication --- .../Builder/AbpRegistrationBuilderExtensions.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs index 2bf2d30605..d587d556d8 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Builder/AbpRegistrationBuilderExtensions.cs @@ -105,14 +105,16 @@ public static class AbpRegistrationBuilderExtensions where TActivatorData : ReflectionActivatorData { // Enable Property Injection only for types in an assembly containing an AbpModule and without a DisablePropertyInjection attribute on class or properties. + if (!implementationType.GetCustomAttributes(typeof(DisablePropertyInjectionAttribute), true).IsNullOrEmpty()) + { + return registrationBuilder; + } + if (moduleContainer.Modules.Any(m => m.AllAssemblies.Contains(implementationType.Assembly))) { - if (implementationType.GetCustomAttributes(typeof(DisablePropertyInjectionAttribute), true).IsNullOrEmpty()) - { - registrationBuilder = registrationBuilder.PropertiesAutowired(new AbpPropertySelector(false)); - } + registrationBuilder = registrationBuilder.PropertiesAutowired(new AbpPropertySelector(false)); } - else if (implementationType.GetCustomAttributes(typeof(DisablePropertyInjectionAttribute), true).IsNullOrEmpty()) + else { nonModuleAssemblies?.Add(implementationType.Assembly); }