comparison Source/Aspects/Builders/ClearCacheAspectBuilder.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
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 }