@@ -14,15 +14,17 @@ public class ModuleWeaver
1414 {
1515 #region Constants
1616
17- private const string CacheAttributeName = "CacheAttribute" ;
17+ public const string CacheAttributeName = "CacheAttribute" ;
1818
19- private const string CacheGetterName = "Cache" ;
19+ public const string CacheGetterName = "Cache" ;
2020
21- private const string CacheTypeContainsMethodName = "Contains" ;
21+ public const string CacheTypeContainsMethodName = "Contains" ;
2222
23- private const string CacheTypeRetrieveMethodName = "Retrieve" ;
23+ public const string CacheTypeRetrieveMethodName = "Retrieve" ;
2424
25- private const string CacheTypeStoreMethodName = "Store" ;
25+ public const string CacheTypeStoreMethodName = "Store" ;
26+
27+ public const string NoCacheAttributeName = "NoCacheAttribute" ;
2628
2729 #endregion
2830
@@ -137,18 +139,21 @@ private bool CheckCacheTypeMethods(TypeDefinition cacheType)
137139 private void RemoveReference ( )
138140 {
139141 AssemblyNameReference referenceToRemove =
140- ModuleDefinition . AssemblyReferences . FirstOrDefault ( x => x . Name == "MethodCache" ) ;
142+ ModuleDefinition . AssemblyReferences . FirstOrDefault ( x => x . Name == "MethodCache.Attributes.dll" ) ;
143+
141144 if ( referenceToRemove == null )
142145 {
143- LogInfo ( "\t No reference to 'MethodCache.dll' found. References not modified." ) ;
146+ LogInfo ( "No reference to 'MethodCache.Attributes.dll' found. References not modified." ) ;
147+
144148 return ;
145149 }
146150
147151 ModuleDefinition . AssemblyReferences . Remove ( referenceToRemove ) ;
148- LogInfo ( "\t Removing reference to 'MethodCache.dll'." ) ;
152+
153+ LogInfo ( "Removing reference to 'MethodCache.Attributes.dll'." ) ;
149154 }
150155
151- private IEnumerable < MethodDefinition > SelectMethods ( ModuleDefinition moduleDefinition , string cacheAttributeName )
156+ private IEnumerable < MethodDefinition > SelectMethods ( ModuleDefinition moduleDefinition , string cacheAttributeName , string noCacheAttributeName )
152157 {
153158 LogInfo ( string . Format ( "Searching for Methods in assembly ({0})." , moduleDefinition . Name ) ) ;
154159
@@ -159,15 +164,23 @@ private IEnumerable<MethodDefinition> SelectMethods(ModuleDefinition moduleDefin
159164 definitions . UnionWith (
160165 moduleDefinition . Types . Where ( x => x . IsClass && x . ContainsAttribute ( cacheAttributeName ) ) . SelectMany ( x => x . Methods )
161166 . Where (
162- x =>
167+ x => ! x . ContainsAttribute ( noCacheAttributeName ) && (
163168 ! x . IsSpecialName && ! x . IsGetter && ! x . IsSetter && ! x . IsConstructor &&
164- ! x . ContainsAttribute ( moduleDefinition . ImportType < CompilerGeneratedAttribute > ( ) ) ) ) ;
169+ ! x . ContainsAttribute ( moduleDefinition . ImportType < CompilerGeneratedAttribute > ( ) ) ) ) ) ;
170+
171+ // Remove CacheAttributes and NoCacheAttributes
172+ definitions . ToList ( ) . ForEach ( x => x . RemoveAttribute ( cacheAttributeName ) ) ;
173+ definitions . ToList ( ) . ForEach ( x => x . DeclaringType . RemoveAttribute ( cacheAttributeName ) ) ;
174+
175+ moduleDefinition . Types . SelectMany ( x => x . Methods ) . ToList ( ) . ForEach ( x => x . RemoveAttribute ( NoCacheAttributeName ) ) ;
165176
166177 return definitions ;
167178 }
168179
169180 private void WeaveMethod ( MethodDefinition methodDefinition )
170181 {
182+ methodDefinition . Body . InitLocals = true ;
183+
171184 methodDefinition . Body . SimplifyMacros ( ) ;
172185
173186 Instruction firstInstruction = methodDefinition . Body . Instructions . First ( ) ;
@@ -201,8 +214,7 @@ private void WeaveMethod(MethodDefinition methodDefinition)
201214 builder . Append ( string . Format ( "_{{{0}}}" , i ) ) ;
202215 }
203216
204- Instruction current = firstInstruction
205- . Prepend ( processor . Create ( OpCodes . Ldstr , builder . ToString ( ) ) , processor ) ;
217+ Instruction current = firstInstruction . Prepend ( processor . Create ( OpCodes . Ldstr , builder . ToString ( ) ) , processor ) ;
206218
207219 // Create object[] for string.format
208220 current = current
@@ -214,7 +226,8 @@ private void WeaveMethod(MethodDefinition methodDefinition)
214226 for ( int i = 0 ; i < methodDefinition . Parameters . Count ; i ++ )
215227 {
216228 current = current
217- . AppendLdloc ( processor , objectArrayIndex ) . AppendLdcI4 ( processor , i )
229+ . AppendLdloc ( processor , objectArrayIndex )
230+ . AppendLdcI4 ( processor , i )
218231 . AppendLdarg ( processor , i + 1 )
219232 . AppendBoxIfNecessary ( processor , methodDefinition . Parameters [ i ] . ParameterType )
220233 . Append ( processor . Create ( OpCodes . Stelem_Ref ) , processor ) ;
@@ -223,7 +236,8 @@ private void WeaveMethod(MethodDefinition methodDefinition)
223236 // Call string.format
224237 current = current
225238 . AppendLdloc ( processor , objectArrayIndex )
226- . Append ( processor . Create ( OpCodes . Call , methodDefinition . Module . ImportMethod < string > ( "Format" , new [ ] { typeof ( string ) , typeof ( object [ ] ) } ) ) , processor )
239+ . Append ( processor . Create ( OpCodes . Call ,
240+ methodDefinition . Module . ImportMethod < string > ( "Format" , new [ ] { typeof ( string ) , typeof ( object [ ] ) } ) ) , processor )
227241 . AppendStloc ( processor , cacheKeyIndex ) ;
228242
229243 if ( IsDebugBuild )
@@ -232,7 +246,8 @@ private void WeaveMethod(MethodDefinition methodDefinition)
232246 current = current
233247 . AppendLdstr ( processor , "CacheKey created: {0}" )
234248 . AppendLdloc ( processor , cacheKeyIndex )
235- . Append ( processor . Create ( OpCodes . Call , methodDefinition . Module . ImportMethod < string > ( "Format" , new [ ] { typeof ( string ) , typeof ( object ) } ) ) , processor )
249+ . Append ( processor . Create ( OpCodes . Call ,
250+ methodDefinition . Module . ImportMethod < string > ( "Format" , new [ ] { typeof ( string ) , typeof ( object ) } ) ) , processor )
236251 . Append ( processor . Create ( OpCodes . Call ,
237252 methodDefinition . Module . ImportMethod ( typeof ( Debug ) , "WriteLine" , new [ ] { typeof ( string ) } ) ) , processor ) ;
238253 }
@@ -243,7 +258,8 @@ private void WeaveMethod(MethodDefinition methodDefinition)
243258
244259 TypeDefinition propertyGetReturnTypeDefinition = propertyGet . ReturnType . Resolve ( ) ;
245260
246- current = current . Append ( processor . Create ( OpCodes . Ldarg_0 ) , processor )
261+ current = current
262+ . Append ( processor . Create ( OpCodes . Ldarg_0 ) , processor )
247263 . Append ( processor . Create ( OpCodes . Call , methodDefinition . Module . Import ( propertyGet ) ) , processor )
248264 . AppendLdloc ( processor , cacheKeyIndex )
249265 . Append ( processor . Create ( OpCodes . Callvirt ,
@@ -254,13 +270,11 @@ private void WeaveMethod(MethodDefinition methodDefinition)
254270 // False branche (store value in cache of each return instruction)
255271 foreach ( Instruction returnInstruction in returnInstructions )
256272 {
257- returnInstruction . Previous
258- . AppendStloc ( processor , resultIndex ) ;
273+ returnInstruction . Previous . AppendStloc ( processor , resultIndex ) ;
259274
260275 if ( IsDebugBuild )
261276 {
262- returnInstruction . Previous
263- . AppendDebugWrite ( processor , "Storing to cache." , methodDefinition . Module ) ;
277+ returnInstruction . Previous . AppendDebugWrite ( processor , "Storing to cache." , methodDefinition . Module ) ;
264278 }
265279
266280 returnInstruction . Previous
@@ -277,27 +291,25 @@ private void WeaveMethod(MethodDefinition methodDefinition)
277291
278292 if ( IsDebugBuild )
279293 {
280- current = current
281- . AppendDebugWrite ( processor , "Loading from cache." , methodDefinition . Module ) ;
294+ current = current . AppendDebugWrite ( processor , "Loading from cache." , methodDefinition . Module ) ;
282295 }
283296
284297 // Start of branche true
285- current = current
286- . Append ( processor . Create ( OpCodes . Ldarg_0 ) , processor )
298+ current = current . Append ( processor . Create ( OpCodes . Ldarg_0 ) , processor )
287299 . Append ( processor . Create ( OpCodes . Call , methodDefinition . Module . Import ( propertyGet ) ) , processor )
288300 . AppendLdloc ( processor , cacheKeyIndex )
289301 . Append ( processor . Create ( OpCodes . Callvirt ,
290302 methodDefinition . Module . Import ( CacheTypeGetRetrieveMethod ( propertyGetReturnTypeDefinition , CacheTypeRetrieveMethodName ) )
291- . MakeGeneric ( new [ ] { methodDefinition . ReturnType } ) ) ,
292- processor )
293- . AppendStloc ( processor , resultIndex ) . Append ( processor . Create ( OpCodes . Br , returnInstructions . Last ( ) . Previous ) , processor ) ;
303+ . MakeGeneric ( new [ ] { methodDefinition . ReturnType } ) ) , processor )
304+ . AppendStloc ( processor , resultIndex )
305+ . Append ( processor . Create ( OpCodes . Br , returnInstructions . Last ( ) . Previous ) , processor ) ;
294306
295307 methodDefinition . Body . OptimizeMacros ( ) ;
296308 }
297309
298310 private void WeaveMethods ( )
299311 {
300- IEnumerable < MethodDefinition > methodDefinitions = SelectMethods ( ModuleDefinition , CacheAttributeName ) ;
312+ IEnumerable < MethodDefinition > methodDefinitions = SelectMethods ( ModuleDefinition , CacheAttributeName , NoCacheAttributeName ) ;
301313
302314 foreach ( MethodDefinition methodDefinition in methodDefinitions )
303315 {
0 commit comments