TestMetadataCache
Caches static information for ITestAction to reduce re-calculations and memory allocations from reflection.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace NUnit.Framework.Internal.Builders
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal static class TestMetadataCache
{
[System.Runtime.CompilerServices.Nullable(0)]
internal sealed class TestMetadata
{
public ITestAction[] TestActionAttributes { get; }
public TestMetadata(Type testType)
{
TestActionAttributes = GetActionsForType(testType);
}
private static ITestAction[] GetActionsForType([System.Runtime.CompilerServices.Nullable(2)] Type type)
{
if ((object)type == null || type == typeof(object))
return Array.Empty<ITestAction>();
List<ITestAction> list = new List<ITestAction>();
list.AddRange(GetActionsForType(type.GetTypeInfo().BaseType));
Type[] declaredInterfaces = TypeHelper.GetDeclaredInterfaces(type);
foreach (Type type2 in declaredInterfaces) {
list.AddRange(type2.GetTypeInfo().GetAttributes<ITestAction>(false));
}
list.AddRange(type.GetTypeInfo().GetAttributes<ITestAction>(false));
return list.ToArray();
}
}
private static readonly ConcurrentDictionary<Type, TestMetadata> Cache = new ConcurrentDictionary<Type, TestMetadata>();
internal static TestMetadata Get(Type testType)
{
return Cache.GetOrAdd(testType, (Type m) => new TestMetadata(m));
}
}
}