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