Skip to content

Commit ee87ea5

Browse files
Refactor GetCustomAttributes method in /Utilities/Reflection.cs
1 parent 054c3c9 commit ee87ea5

File tree

1 file changed

+14
-36
lines changed

1 file changed

+14
-36
lines changed

src/MyTested.AspNetCore.Mvc.Abstractions/Utilities/Reflection.cs

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ public static class Reflection
2020
private const bool ShouldInheritAttributes = false;
2121

2222
private static readonly ConcurrentDictionary<Type, ConstructorInfo> TypesWithOneConstructorCache = new ConcurrentDictionary<Type, ConstructorInfo>();
23-
private static readonly ConcurrentDictionary<Type, object> TypeAttributesCache = new ConcurrentDictionary<Type, object>();
24-
private static readonly ConcurrentDictionary<Type, object> MethodAttributesCache = new ConcurrentDictionary<Type, object>();
23+
private static readonly ConcurrentDictionary<Type, IEnumerable<object>> TypeAttributesCache = new ConcurrentDictionary<Type, IEnumerable<object>>();
24+
private static readonly ConcurrentDictionary<MethodInfo, IEnumerable<object>> MethodAttributesCache = new ConcurrentDictionary<MethodInfo, IEnumerable<object>>();
2525
private static readonly ConcurrentDictionary<Type, string> FriendlyTypeNames = new ConcurrentDictionary<Type, string>();
2626
private static readonly ConcurrentDictionary<Type, string> FullFriendlyTypeNames = new ConcurrentDictionary<Type, string>();
2727

@@ -291,19 +291,10 @@ public static IEnumerable<object> GetCustomAttributes(object obj, bool shouldInh
291291
{
292292
var type = obj.GetType();
293293
var attributes = type.GetTypeInfo().GetCustomAttributes(shouldInherit);
294+
UpdateAttributesIfNeeded(type, attributes, TypeAttributesCache);
294295

295-
if (!HasAnyAttributes(attributes, TypeAttributesCache))
296-
{
297-
return attributes;
298-
}
299-
300-
if (attributes.Length == TypeAttributesCache.Count)
301-
{
302-
return TypeAttributesCache.Values;
303-
}
304-
305-
CacheAttributes(attributes, TypeAttributesCache);
306-
return TypeAttributesCache.Values;
296+
return TypeAttributesCache
297+
.GetOrAdd(type, _ => attributes);
307298
}
308299

309300
/// <summary>
@@ -315,19 +306,10 @@ public static IEnumerable<object> GetCustomAttributes(object obj, bool shouldInh
315306
public static IEnumerable<object> GetCustomAttributes(MethodInfo method, bool shouldInherit = ShouldInheritAttributes)
316307
{
317308
var attributes = method.GetCustomAttributes(shouldInherit);
309+
UpdateAttributesIfNeeded(method, attributes, MethodAttributesCache);
318310

319-
if (!HasAnyAttributes(attributes, MethodAttributesCache))
320-
{
321-
return attributes;
322-
}
323-
324-
if (attributes.Length == MethodAttributesCache.Count)
325-
{
326-
return MethodAttributesCache.Values;
327-
}
328-
329-
CacheAttributes(attributes, MethodAttributesCache);
330-
return MethodAttributesCache.Values;
311+
return MethodAttributesCache
312+
.GetOrAdd(method, _ => attributes);
331313
}
332314

333315
/// <summary>
@@ -757,21 +739,17 @@ private static bool ObjectPropertiesAreDeeplyEqual(
757739
return result.Success;
758740
}
759741

760-
private static void CacheAttributes(IEnumerable<object> attributes, ConcurrentDictionary<Type, object> result)
742+
private static void UpdateAttributesIfNeeded<T>(
743+
T key,
744+
object[] attributes,
745+
ConcurrentDictionary<T, IEnumerable<object>> result)
761746
{
762-
foreach (var attribute in attributes)
747+
if (result.ContainsKey(key))
763748
{
764-
var attributeType = attribute.GetType();
765-
if (!result.ContainsKey(attributeType))
766-
{
767-
result.TryAdd(attributeType, attribute);
768-
}
749+
result.AddOrUpdate(key, attributes, (dictKey, oldValue) => attributes);
769750
}
770751
}
771752

772-
private static bool HasAnyAttributes(IReadOnlyCollection<object> attributes, ConcurrentDictionary<Type, object> result)
773-
=> attributes.Count != 0 || result.Any();
774-
775753
private static string GetFriendlyTypeName(Type type, bool useFullName)
776754
{
777755
const string anonymousTypePrefix = "<>f__";

0 commit comments

Comments
 (0)