Skip to content

Commit

Permalink
Merge pull request #1438 from hemirunner426/develop
Browse files Browse the repository at this point in the history
check if generic type assembly has been added to set
  • Loading branch information
tillig authored Dec 16, 2024
2 parents d2ed00a + 1b3b07d commit 172f06a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/Autofac/Util/Cache/TypeAssemblyReferenceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ public static IEnumerable<Assembly> GetAllReferencedAssemblies(MemberInfo member
public static IEnumerable<Assembly> GetAllReferencedAssemblies(MemberInfo memberInfo, HashSet<Assembly> holdingSet)
{
holdingSet.Clear();
var activeWorkingSet = new HashSet<Type>();

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;
Expand All @@ -56,26 +57,33 @@ public static IEnumerable<Assembly> GetAllReferencedAssemblies(MemberInfo member
/// Add to a provided <see cref="HashSet{T}"/> all assemblies referenced by a given type.
/// </summary>
/// <param name="inputType">The type to retrieve references for.</param>
/// <param name="activeWorkingSet">A set to track types which have been processed.</param>
/// <param name="holdingSet">A set to add any assemblies to.</param>
private static void PopulateAllReferencedAssemblies(Type inputType, HashSet<Assembly> holdingSet)
private static void PopulateAllReferencedAssemblies(Type inputType, HashSet<Type> activeWorkingSet, HashSet<Assembly> 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)
{
PopulateAllReferencedAssemblies(genericArgumentType, holdingSet);
if (activeWorkingSet.Contains(genericArgumentType))
{
continue;
}

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);
}
}
}
10 changes: 10 additions & 0 deletions test/Autofac.Test/Util/Cache/TypeAssemblyReferenceProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class TypeAssemblyReferenceProviderTests
[InlineData(typeof(IEnumerable<IIndex<int, Assert>>), new[] { typeof(IEnumerable<>), typeof(IIndex<,>), typeof(Assert) })]
[InlineData(typeof(DerivedClass), new[] { typeof(DerivedClass), typeof(RegistrationBuilder<,,>), typeof(Assert) })]
[InlineData(typeof(GenericDerivedClass<Assert>), 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);
Expand Down Expand Up @@ -50,6 +51,15 @@ public void MemberInfoReferencesCanBeDetermined()
}
}

private abstract class GenericAbstractClass<T>
where T : class
{
}

private class DerivedClassFromGenericAbstract : GenericAbstractClass<DerivedClassFromGenericAbstract>
{
}

private class DerivedClass
: RegistrationBuilder<Assert, SimpleActivatorData, SingleRegistrationStyle>
{
Expand Down

0 comments on commit 172f06a

Please sign in to comment.