Mercurial > pub > bltoolkit
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 } |