From a9bef65d9c01c211ae98500d4bb7fa77a8590dff Mon Sep 17 00:00:00 2001 From: Allen Anderson Date: Thu, 5 Dec 2024 09:53:06 -0700 Subject: [PATCH 1/3] check if generic type assembly has been added to set --- .../Util/Cache/TypeAssemblyReferenceProvider.cs | 5 +++++ .../Util/Cache/TypeAssemblyReferenceProviderTests.cs | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/Autofac/Util/Cache/TypeAssemblyReferenceProvider.cs b/src/Autofac/Util/Cache/TypeAssemblyReferenceProvider.cs index 0d56cf39c..909b9934d 100644 --- a/src/Autofac/Util/Cache/TypeAssemblyReferenceProvider.cs +++ b/src/Autofac/Util/Cache/TypeAssemblyReferenceProvider.cs @@ -68,6 +68,11 @@ private static void PopulateAllReferencedAssemblies(Type inputType, HashSet a.DefinedTypes.Contains(genericArgumentType))) + { + continue; + } + PopulateAllReferencedAssemblies(genericArgumentType, holdingSet); } diff --git a/test/Autofac.Test/Util/Cache/TypeAssemblyReferenceProviderTests.cs b/test/Autofac.Test/Util/Cache/TypeAssemblyReferenceProviderTests.cs index a8cfaf6ea..31c901d60 100644 --- a/test/Autofac.Test/Util/Cache/TypeAssemblyReferenceProviderTests.cs +++ b/test/Autofac.Test/Util/Cache/TypeAssemblyReferenceProviderTests.cs @@ -18,6 +18,7 @@ public class TypeAssemblyReferenceProviderTests [InlineData(typeof(IEnumerable>), new[] { typeof(IEnumerable<>), typeof(IIndex<,>), typeof(Assert) })] [InlineData(typeof(DerivedClass), new[] { typeof(DerivedClass), typeof(RegistrationBuilder<,,>), typeof(Assert) })] [InlineData(typeof(GenericDerivedClass), new[] { typeof(DerivedClass), typeof(RegistrationBuilder<,,>), typeof(Assert), typeof(object) })] + [InlineData(typeof(DerivedClassFromGenericAbstract), new[] { typeof(DerivedClassFromGenericAbstract) })] public void TypeReferencesCanBeDetermined(Type inputType, Type[] expandedTypeAssemblies) { Assert.NotNull(expandedTypeAssemblies); @@ -50,6 +51,16 @@ public void MemberInfoReferencesCanBeDetermined() } } + private abstract class GenericAbstractClass where T : class + { + + } + + private class DerivedClassFromGenericAbstract : GenericAbstractClass + { + + } + private class DerivedClass : RegistrationBuilder { From c57e0897ff20db0aebc8be8e3afedc48e217f3e9 Mon Sep 17 00:00:00 2001 From: Allen Anderson Date: Thu, 5 Dec 2024 10:08:55 -0700 Subject: [PATCH 2/3] fix formatting --- .../Util/Cache/TypeAssemblyReferenceProviderTests.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/Autofac.Test/Util/Cache/TypeAssemblyReferenceProviderTests.cs b/test/Autofac.Test/Util/Cache/TypeAssemblyReferenceProviderTests.cs index 31c901d60..1c6bf6432 100644 --- a/test/Autofac.Test/Util/Cache/TypeAssemblyReferenceProviderTests.cs +++ b/test/Autofac.Test/Util/Cache/TypeAssemblyReferenceProviderTests.cs @@ -51,14 +51,13 @@ public void MemberInfoReferencesCanBeDetermined() } } - private abstract class GenericAbstractClass where T : class + private abstract class GenericAbstractClass + where T : class { - } private class DerivedClassFromGenericAbstract : GenericAbstractClass { - } private class DerivedClass From 1b3b07d785059bdbef1c4d15c167230db4b9699a Mon Sep 17 00:00:00 2001 From: Allen Anderson Date: Fri, 6 Dec 2024 10:16:40 -0700 Subject: [PATCH 3/3] track processed types instead of enumerating assembly types --- .../Util/Cache/TypeAssemblyReferenceProvider.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Autofac/Util/Cache/TypeAssemblyReferenceProvider.cs b/src/Autofac/Util/Cache/TypeAssemblyReferenceProvider.cs index 909b9934d..c85e30902 100644 --- a/src/Autofac/Util/Cache/TypeAssemblyReferenceProvider.cs +++ b/src/Autofac/Util/Cache/TypeAssemblyReferenceProvider.cs @@ -39,14 +39,15 @@ public static IEnumerable GetAllReferencedAssemblies(MemberInfo member public static IEnumerable GetAllReferencedAssemblies(MemberInfo memberInfo, HashSet holdingSet) { holdingSet.Clear(); + var activeWorkingSet = new HashSet(); if (memberInfo is Type keyType) { - PopulateAllReferencedAssemblies(keyType, holdingSet); + PopulateAllReferencedAssemblies(keyType, activeWorkingSet, holdingSet); } else if (memberInfo.DeclaringType is Type declaredType) { - PopulateAllReferencedAssemblies(declaredType, holdingSet); + PopulateAllReferencedAssemblies(declaredType, activeWorkingSet, holdingSet); } return holdingSet; @@ -56,31 +57,33 @@ public static IEnumerable GetAllReferencedAssemblies(MemberInfo member /// Add to a provided all assemblies referenced by a given type. /// /// The type to retrieve references for. + /// A set to track types which have been processed. /// A set to add any assemblies to. - private static void PopulateAllReferencedAssemblies(Type inputType, HashSet holdingSet) + private static void PopulateAllReferencedAssemblies(Type inputType, HashSet activeWorkingSet, HashSet holdingSet) { if (inputType.IsArray && inputType.GetElementType() is Type elementType) { - PopulateAllReferencedAssemblies(elementType, holdingSet); + PopulateAllReferencedAssemblies(elementType, activeWorkingSet, holdingSet); } var genericArguments = inputType.GenericTypeArguments; foreach (var genericArgumentType in genericArguments) { - if (holdingSet.Any(a => a.DefinedTypes.Contains(genericArgumentType))) + if (activeWorkingSet.Contains(genericArgumentType)) { continue; } - PopulateAllReferencedAssemblies(genericArgumentType, holdingSet); + PopulateAllReferencedAssemblies(genericArgumentType, activeWorkingSet, holdingSet); } holdingSet.Add(inputType.Assembly); + activeWorkingSet.Add(inputType); if (inputType.BaseType is not null && inputType.BaseType != typeof(object)) { - PopulateAllReferencedAssemblies(inputType.BaseType, holdingSet); + PopulateAllReferencedAssemblies(inputType.BaseType, activeWorkingSet, holdingSet); } } }