Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 509d8b9

Browse files
author
Dresel
committed
Reorganization, added NoCacheAttribute
1 parent 83c6de0 commit 509d8b9

23 files changed

Lines changed: 371 additions & 137 deletions

CommonAssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
[assembly: AssemblyTitle("MethodCache.Fody")]
44
[assembly: AssemblyProduct("MethodCache.Fody")]
5-
[assembly: AssemblyVersion("1.2.0.0")]
6-
[assembly: AssemblyFileVersion("1.2.0.0")]
5+
[assembly: AssemblyVersion("1.3.0.0")]
6+
[assembly: AssemblyFileVersion("1.3.0.0")]

MethodCache.ReferenceAssembly/Cache/CacheAttribute.cs renamed to MethodCache.Attributes/CacheAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace MethodCache.ReferenceAssembly.Cache
1+
namespace MethodCache.Attributes
22
{
33
using System;
44

MethodCache.ReferenceAssembly/MethodCache.ReferenceAssembly.csproj renamed to MethodCache.Attributes/MethodCache.Attributes.csproj

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
<ProjectGuid>{1D0AD049-7240-41CD-8B69-7F48AA5FAA6C}</ProjectGuid>
88
<OutputType>Library</OutputType>
99
<AppDesignerFolder>Properties</AppDesignerFolder>
10-
<RootNamespace>MethodCache.ReferenceAssembly</RootNamespace>
11-
<AssemblyName>MethodCache.ReferenceAssembly</AssemblyName>
10+
<RootNamespace>MethodCache.Attributes</RootNamespace>
11+
<AssemblyName>MethodCache.Attributes</AssemblyName>
1212
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
1313
<TargetFrameworkProfile>Profile1</TargetFrameworkProfile>
1414
<FileAlignment>512</FileAlignment>
@@ -22,7 +22,7 @@
2222
<DefineConstants>DEBUG;TRACE</DefineConstants>
2323
<ErrorReport>prompt</ErrorReport>
2424
<WarningLevel>4</WarningLevel>
25-
<DocumentationFile>bin\Debug\MethodCache.ReferenceAssembly.xml</DocumentationFile>
25+
<DocumentationFile>bin\Debug\MethodCache.Attributes.xml</DocumentationFile>
2626
</PropertyGroup>
2727
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
2828
<DebugType>pdbonly</DebugType>
@@ -31,21 +31,14 @@
3131
<DefineConstants>TRACE</DefineConstants>
3232
<ErrorReport>prompt</ErrorReport>
3333
<WarningLevel>4</WarningLevel>
34-
<DocumentationFile>bin\Release\MethodCache.ReferenceAssembly.xml</DocumentationFile>
34+
<DocumentationFile>bin\Release\MethodCache.Attributes.xml</DocumentationFile>
3535
</PropertyGroup>
3636
<ItemGroup>
3737
<Compile Include="..\CommonAssemblyInfo.cs">
3838
<Link>CommonAssemblyInfo.cs</Link>
3939
</Compile>
40-
<Compile Include="Cache\CacheAttribute.cs" />
41-
<Compile Include="Cache\DictionaryCache.cs" />
42-
<Compile Include="Cache\ICache.cs" />
43-
<Compile Include="MethodResult.cs" />
44-
<Compile Include="TestClass1.cs" />
45-
<Compile Include="TestClass2.cs" />
46-
<Compile Include="TestClass3.cs" />
47-
<Compile Include="TestClass4.cs" />
48-
<Compile Include="TestClass5.cs" />
40+
<Compile Include="CacheAttribute.cs" />
41+
<Compile Include="NoCacheAttribute.cs" />
4942
</ItemGroup>
5043
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
5144
</Project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace MethodCache.Attributes
2+
{
3+
using System;
4+
5+
/// <summary>
6+
/// Prevents caching the output of this method when CacheAttribute is used on class level.
7+
/// </summary>
8+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
9+
public class NoCacheAttribute : Attribute
10+
{
11+
}
12+
}

MethodCache.Fody/CecilHelper.cs

Lines changed: 17 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -80,58 +80,17 @@ public static Instruction AppendStloc(this Instruction instruction, ILProcessor
8080

8181
public static bool ContainsAttribute(this MethodDefinition methodDefinition, MemberReference attributeType)
8282
{
83-
CustomAttribute attribute =
84-
methodDefinition.CustomAttributes.FirstOrDefault(x => x.Constructor.DeclaringType.FullName == attributeType.FullName);
85-
86-
if (attribute != null)
87-
{
88-
methodDefinition.CustomAttributes.Remove(attribute);
89-
return true;
90-
}
91-
92-
return false;
83+
return methodDefinition.CustomAttributes.Any(x => x.Constructor.DeclaringType.FullName == attributeType.FullName);
9384
}
9485

9586
public static bool ContainsAttribute(this MethodDefinition methodDefinition, string attributeTypeName)
9687
{
97-
CustomAttribute attribute =
98-
methodDefinition.CustomAttributes.FirstOrDefault(x => x.Constructor.DeclaringType.Name == attributeTypeName);
99-
100-
if (attribute != null)
101-
{
102-
methodDefinition.CustomAttributes.Remove(attribute);
103-
return true;
104-
}
105-
106-
return false;
107-
}
108-
109-
public static bool ContainsAttribute(this TypeDefinition typeDefinition, MemberReference attributeType)
110-
{
111-
CustomAttribute attribute =
112-
typeDefinition.CustomAttributes.FirstOrDefault(x => x.Constructor.DeclaringType.FullName == attributeType.FullName);
113-
114-
if (attribute != null)
115-
{
116-
typeDefinition.CustomAttributes.Remove(attribute);
117-
return true;
118-
}
119-
120-
return false;
88+
return methodDefinition.CustomAttributes.Any(x => x.Constructor.DeclaringType.Name == attributeTypeName);
12189
}
12290

12391
public static bool ContainsAttribute(this TypeDefinition typeDefinition, string attributeTypeName)
12492
{
125-
CustomAttribute attribute =
126-
typeDefinition.CustomAttributes.FirstOrDefault(x => x.Constructor.DeclaringType.Name == attributeTypeName);
127-
128-
if (attribute != null)
129-
{
130-
typeDefinition.CustomAttributes.Remove(attribute);
131-
return true;
132-
}
133-
134-
return false;
93+
return typeDefinition.CustomAttributes.Any(x => x.Constructor.DeclaringType.Name == attributeTypeName);
13594
}
13695

13796
public static MethodDefinition GetInheritedPropertyGet(this TypeDefinition baseType, string propertyName)
@@ -269,6 +228,20 @@ public static Instruction Prepend(this Instruction instruction, Instruction inst
269228
return instructionBefore;
270229
}
271230

231+
public static void RemoveAttribute(this MethodDefinition methodDefinition, string attributeTypeName)
232+
{
233+
methodDefinition.CustomAttributes
234+
.Where(x => x.Constructor.DeclaringType.Name == attributeTypeName).ToList()
235+
.ForEach(x => methodDefinition.CustomAttributes.Remove(x));
236+
}
237+
238+
public static void RemoveAttribute(this TypeDefinition typeDefinition, string attributeTypeName)
239+
{
240+
typeDefinition.CustomAttributes
241+
.Where(x => x.Constructor.DeclaringType.Name == attributeTypeName).ToList()
242+
.ForEach(x => typeDefinition.CustomAttributes.Remove(x));
243+
}
244+
272245
#endregion
273246
}
274247
}

MethodCache.Fody/ModuleWeaver.cs

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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("\tNo 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("\tRemoving 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
{

MethodCache.NuGet/MethodCache.Nuget.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
<Copy SourceFiles="$(SolutionDir)MethodCache.Fody\bin\$(ConfigurationName)\MethodCache.Fody.dll" DestinationFolder="$(SolutionDir)NuGetBuild" />
3232
<Copy SourceFiles="$(ProjectDir)install.ps1" DestinationFolder="$(SolutionDir)NuGetBuild\Tools" />
3333
<Copy SourceFiles="$(ProjectDir)uninstall.ps1" DestinationFolder="$(SolutionDir)NuGetBuild\Tools" />
34-
<Copy SourceFiles="$(SolutionDir)MethodCache.ReferenceAssembly\bin\$(ConfigurationName)\MethodCache.ReferenceAssembly.dll" DestinationFolder="$(SolutionDir)NuGetBuild\Lib\portable-net4+sl4+wp7+win8" />
35-
<Copy SourceFiles="$(SolutionDir)MethodCache.ReferenceAssembly\bin\$(ConfigurationName)\MethodCache.ReferenceAssembly.xml" DestinationFolder="$(SolutionDir)NuGetBuild\Lib\portable-net4+sl4+wp7+win8" />
34+
<Copy SourceFiles="$(SolutionDir)MethodCache.Attributes\bin\$(ConfigurationName)\MethodCache.Attributes.dll" DestinationFolder="$(SolutionDir)NuGetBuild\Lib\portable-net4+sl4+wp7+win8" />
35+
<Copy SourceFiles="$(SolutionDir)MethodCache.Attributes\bin\$(ConfigurationName)\MethodCache.Attributes.xml" DestinationFolder="$(SolutionDir)NuGetBuild\Lib\portable-net4+sl4+wp7+win8" />
3636
<PepitaPackage.WeavingTask NuGetBuildDirectory="$(SolutionDir)NuGetBuild" MetadataAssembly="$(SolutionDir)MethodCache.Fody\bin\$(ConfigurationName)\MethodCache.Fody.dll" />
3737
</Target>
3838
<ItemGroup>
@@ -43,9 +43,9 @@
4343
</ProjectReference>
4444
</ItemGroup>
4545
<ItemGroup>
46-
<ProjectReference Include="..\MethodCache.ReferenceAssembly\MethodCache.ReferenceAssembly.csproj">
46+
<ProjectReference Include="..\MethodCache.Attributes\MethodCache.Attributes.csproj">
4747
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
48-
<Name>MethodCache.ReferenceAssembly</Name>
48+
<Name>MethodCache.Attributes</Name>
4949
<Project>{1D0AD049-7240-41CD-8B69-7F48AA5FAA6C}</Project>
5050
</ProjectReference>
5151
</ItemGroup>

MethodCache.ReferenceAssembly/MethodResult.cs

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)