Skip to content

Commit 4547d16

Browse files
authored
Merge pull request #1415 from SergeiPavlov/MemoizeAttribute
Optimization: Memoize `RequiredMemberAttribute` search
2 parents b843130 + 3fe2ddf commit 4547d16

File tree

2 files changed

+22
-9
lines changed

2 files changed

+22
-9
lines changed

src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,20 @@ public void ConfigurePipeline(IComponentRegistryServices componentRegistryServic
8181
#if NET7_0_OR_GREATER
8282
// The RequiredMemberAttribute has Inherit = false on its AttributeUsage options,
8383
// so we can't use the expected GetCustomAttribute(inherit: true) option, and must walk the tree.
84-
var currentType = _implementationType;
85-
while (currentType is not null && !currentType.Equals(typeof(object)))
86-
{
87-
if (currentType.GetCustomAttribute<RequiredMemberAttribute>() is not null)
84+
_anyRequiredMembers = ReflectionCacheSet.Shared.Internal.HasRequiredMemberAttribute.GetOrAdd(
85+
_implementationType,
86+
static t =>
8887
{
89-
_anyRequiredMembers = true;
90-
break;
91-
}
88+
for (var currentType = t; currentType is not null && currentType != typeof(object); currentType = currentType.BaseType)
89+
{
90+
if (currentType.GetCustomAttribute<RequiredMemberAttribute>() is not null)
91+
{
92+
return true;
93+
}
94+
}
9295

93-
currentType = currentType.BaseType;
94-
}
96+
return false;
97+
});
9598
#else
9699
_anyRequiredMembers = false;
97100
#endif

src/Autofac/Core/InternalReflectionCaches.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ internal class InternalReflectionCaches
5959
/// </summary>
6060
public ReflectionCacheDictionary<Type, Type> GenericTypeDefinitionByType { get; }
6161

62+
#if NET7_0_OR_GREATER
63+
/// <summary>
64+
/// Gets a cache used by <see cref="ReflectionActivator"/>.
65+
/// </summary>
66+
public ReflectionCacheDictionary<Type, bool> HasRequiredMemberAttribute { get; }
67+
#endif
68+
6269
/// <summary>
6370
/// Initializes a new instance of the <see cref="InternalReflectionCaches"/> class.
6471
/// </summary>
@@ -78,5 +85,8 @@ public InternalReflectionCaches(ReflectionCacheSet set)
7885
AutowiringInjectableProperties = set.GetOrCreateCache<ReflectionCacheDictionary<Type, IReadOnlyList<PropertyInfo>>>(nameof(AutowiringInjectableProperties));
7986
DefaultPublicConstructors = set.GetOrCreateCache<ReflectionCacheDictionary<Type, ConstructorInfo[]>>(nameof(DefaultPublicConstructors));
8087
GenericTypeDefinitionByType = set.GetOrCreateCache<ReflectionCacheDictionary<Type, Type>>(nameof(GenericTypeDefinitionByType));
88+
#if NET7_0_OR_GREATER
89+
HasRequiredMemberAttribute = set.GetOrCreateCache<ReflectionCacheDictionary<Type, bool>>(nameof(HasRequiredMemberAttribute));
90+
#endif
8191
}
8292
}

0 commit comments

Comments
 (0)