namespace System.Web.Mvc { using System; using System.Collections.Concurrent; using System.Diagnostics; using System.Reflection; using System.Collections.Generic; using System.Collections.ObjectModel; internal static class ReflectedAttributeCache { private static readonly ConcurrentDictionary> _actionMethodSelectorAttributeCache = new ConcurrentDictionary>(); private static readonly ConcurrentDictionary> _actionNameSelectorAttributeCache = new ConcurrentDictionary>(); private static readonly ConcurrentDictionary> _methodFilterAttributeCache = new ConcurrentDictionary>(); private static readonly ConcurrentDictionary> _typeFilterAttributeCache = new ConcurrentDictionary>(); public static ICollection GetTypeFilterAttributes(Type type) { return GetAttributes(_typeFilterAttributeCache, type); } public static ICollection GetMethodFilterAttributes(MethodInfo methodInfo) { return GetAttributes(_methodFilterAttributeCache, methodInfo); } public static ICollection GetActionMethodSelectorAttributes(MethodInfo methodInfo) { return GetAttributes(_actionMethodSelectorAttributeCache, methodInfo); } public static ICollection GetActionNameSelectorAttributes(MethodInfo methodInfo) { return GetAttributes(_actionNameSelectorAttributeCache, methodInfo); } private static ReadOnlyCollection GetAttributes(ConcurrentDictionary> lookup, TMemberInfo memberInfo) where TAttribute : Attribute where TMemberInfo : MemberInfo { Debug.Assert(memberInfo != null); Debug.Assert(lookup != null); return lookup.GetOrAdd(memberInfo, mi => new ReadOnlyCollection((TAttribute[])memberInfo.GetCustomAttributes(typeof(TAttribute), inherit: true))); } } }