0
|
1 using System;
|
|
2 using System.Reflection;
|
|
3 using System.Reflection.Emit;
|
|
4
|
|
5 using BLToolkit.Reflection.Emit;
|
|
6 using BLToolkit.TypeBuilder.Builders;
|
|
7
|
|
8 namespace BLToolkit.Aspects.Builders
|
|
9 {
|
|
10 public class ClearCacheAspectBuilder : AbstractTypeBuilderBase
|
|
11 {
|
|
12 #region Init
|
|
13
|
|
14 public ClearCacheAspectBuilder(Type declaringType, string methodName, Type[] parameterTypes)
|
|
15 {
|
|
16 _declaringType = declaringType;
|
|
17 _methodName = methodName;
|
|
18 _parameterTypes = parameterTypes;
|
|
19 }
|
|
20
|
|
21 private readonly Type _declaringType;
|
|
22 private readonly string _methodName;
|
|
23 private readonly Type[] _parameterTypes;
|
|
24
|
|
25 #endregion
|
|
26
|
|
27 #region Overrides
|
|
28
|
|
29 public override int GetPriority(BuildContext context)
|
|
30 {
|
|
31 return TypeBuilderConsts.Priority.ClearCacheAspect;
|
|
32 }
|
|
33
|
|
34 public override bool IsCompatible(BuildContext context, IAbstractTypeBuilder typeBuilder)
|
|
35 {
|
|
36 return true;
|
|
37 }
|
|
38
|
|
39 public override bool IsApplied(BuildContext context, AbstractTypeBuilderList builders)
|
|
40 {
|
|
41 if (context == null) throw new ArgumentNullException("context");
|
|
42
|
|
43 return context.IsFinallyStep && context.IsMethodOrProperty;
|
|
44 }
|
|
45
|
|
46 #endregion
|
|
47
|
|
48 #region Build
|
|
49
|
|
50 private static int _methodCounter;
|
|
51
|
|
52 public override void Build(BuildContext context)
|
|
53 {
|
|
54 Context = context;
|
|
55
|
|
56 if (string.IsNullOrEmpty(_methodName))
|
|
57 {
|
|
58 FieldBuilder type = Context.CreatePrivateStaticField(
|
|
59 "_type$ClearCacheAspect$" + ++_methodCounter, typeof(Type));
|
|
60
|
|
61 EmitHelper emit = Context.MethodBuilder.Emitter;
|
|
62 Label checkType = emit.DefineLabel();
|
|
63
|
|
64 emit
|
|
65 .ldsfld (type)
|
|
66 .brtrue_s (checkType)
|
|
67 .ldarg_0
|
|
68 .LoadType (_declaringType)
|
|
69 .call (typeof(ClearCacheAspect), "GetType", typeof(object), typeof(Type))
|
|
70 .stsfld (type)
|
|
71 .MarkLabel (checkType)
|
|
72 .ldsfld (type)
|
|
73 .call (typeof(CacheAspect), "ClearCache", typeof(Type))
|
|
74 ;
|
|
75 }
|
|
76 else
|
|
77 {
|
|
78 FieldBuilder methodInfo = Context.CreatePrivateStaticField(
|
|
79 "_methodInfo$ClearCacheAspect$" + ++_methodCounter, typeof(MethodInfo));
|
|
80
|
|
81 EmitHelper emit = Context.MethodBuilder.Emitter;
|
|
82
|
|
83 Label checkMethodInfo = emit.DefineLabel();
|
|
84
|
|
85 emit
|
|
86 .ldsfld (methodInfo)
|
|
87 .brtrue_s (checkMethodInfo)
|
|
88 .ldarg_0
|
|
89 .LoadType (_declaringType)
|
|
90 .ldstrEx (_methodName)
|
|
91 ;
|
|
92
|
|
93 if (_parameterTypes == null || _parameterTypes.Length == 0)
|
|
94 {
|
|
95 emit.ldnull.end();
|
|
96 }
|
|
97 else
|
|
98 {
|
|
99 LocalBuilder field = emit.DeclareLocal(typeof(Type[]));
|
|
100
|
|
101 emit
|
|
102 .ldc_i4_ (_parameterTypes.Length)
|
|
103 .newarr (typeof(Type))
|
|
104 .stloc (field)
|
|
105 ;
|
|
106
|
|
107 for (int i = 0; i < _parameterTypes.Length; i++)
|
|
108 {
|
|
109 emit
|
|
110 .ldloc (field)
|
|
111 .ldc_i4 (i)
|
|
112 .LoadType (_parameterTypes[i])
|
|
113 .stelem_ref
|
|
114 .end()
|
|
115 ;
|
|
116 }
|
|
117
|
|
118 emit.ldloc(field);
|
|
119 }
|
|
120
|
|
121 emit
|
|
122 .call (typeof(ClearCacheAspect), "GetMethodInfo", typeof(object), typeof(Type), typeof(string), typeof(Type[]))
|
|
123 .stsfld (methodInfo)
|
|
124 .MarkLabel (checkMethodInfo)
|
|
125 .ldsfld (methodInfo)
|
|
126 .call (typeof(CacheAspect), "ClearCache", typeof(MethodInfo))
|
|
127 ;
|
|
128 }
|
|
129 }
|
|
130
|
|
131 #endregion
|
|
132 }
|
|
133 }
|