1 namespace System.Web.Mvc { 2 using System; 3 using System.Collections.Concurrent; 4 using System.Diagnostics; 5 using System.Reflection; 6 using System.Collections.Generic; 7 using System.Collections.ObjectModel; 8 9 internal static class ReflectedAttributeCache { 10 private static readonly ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionMethodSelectorAttribute>> _actionMethodSelectorAttributeCache = new ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionMethodSelectorAttribute>>(); 11 private static readonly ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionNameSelectorAttribute>> _actionNameSelectorAttributeCache = new ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionNameSelectorAttribute>>(); 12 private static readonly ConcurrentDictionary<MethodInfo, ReadOnlyCollection<FilterAttribute>> _methodFilterAttributeCache = new ConcurrentDictionary<MethodInfo, ReadOnlyCollection<FilterAttribute>>(); 13 14 private static readonly ConcurrentDictionary<Type, ReadOnlyCollection<FilterAttribute>> _typeFilterAttributeCache = new ConcurrentDictionary<Type, ReadOnlyCollection<FilterAttribute>>(); 15 GetTypeFilterAttributes(Type type)16 public static ICollection<FilterAttribute> GetTypeFilterAttributes(Type type) { 17 return GetAttributes(_typeFilterAttributeCache, type); 18 } 19 GetMethodFilterAttributes(MethodInfo methodInfo)20 public static ICollection<FilterAttribute> GetMethodFilterAttributes(MethodInfo methodInfo) { 21 return GetAttributes(_methodFilterAttributeCache, methodInfo); 22 } 23 GetActionMethodSelectorAttributes(MethodInfo methodInfo)24 public static ICollection<ActionMethodSelectorAttribute> GetActionMethodSelectorAttributes(MethodInfo methodInfo) { 25 return GetAttributes(_actionMethodSelectorAttributeCache, methodInfo); 26 } 27 GetActionNameSelectorAttributes(MethodInfo methodInfo)28 public static ICollection<ActionNameSelectorAttribute> GetActionNameSelectorAttributes(MethodInfo methodInfo) { 29 return GetAttributes(_actionNameSelectorAttributeCache, methodInfo); 30 } 31 32 private static ReadOnlyCollection<TAttribute> GetAttributes<TMemberInfo, TAttribute>(ConcurrentDictionary<TMemberInfo, ReadOnlyCollection<TAttribute>> lookup, TMemberInfo memberInfo) 33 where TAttribute : Attribute 34 where TMemberInfo : MemberInfo { 35 36 Debug.Assert(memberInfo != null); 37 Debug.Assert(lookup != null); 38 return lookup.GetOrAdd(memberInfo, mi => new ReadOnlyCollection<TAttribute>((TAttribute[])memberInfo.GetCustomAttributes(typeof(TAttribute), inherit: true))); 39 } 40 } 41 } 42