Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a NoKey-attribute to skip parameter for cache generation, close… #17

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// <copyright file="ParameterDefinitionExtension.cs" company="Spatial Focus GmbH">
// Copyright (c) Spatial Focus GmbH. All rights reserved.
// </copyright>

namespace SpatialFocus.MethodCache.Fody.Extensions
{
using System;
using System.Linq;
using Mono.Cecil;

public static class ParameterDefinitionExtension
{
public static bool HasNoKeyAttribute(this ParameterDefinition parameterDefinition, References references)
{
if (parameterDefinition == null)
{
throw new ArgumentNullException(nameof(parameterDefinition));
}

if (references == null)
{
throw new ArgumentNullException(nameof(references));
}

TypeReference noKeyAttributeType = references.NoKeyAttributeType.Resolve();

return parameterDefinition.CustomAttributes.Any(classAttribute =>
classAttribute.AttributeType.Resolve().Equals(noKeyAttributeType));
}
}
}
25 changes: 17 additions & 8 deletions src/SpatialFocus.MethodCache.Fody/MemoryCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ public static void AddMethodVariables(MethodWeavingContext methodWeavingContext)
methodWeavingContext.MethodDefinition.DeclaringType.GenericParameters.Count))
.Concat(Enumerable.Repeat(methodWeavingContext.ClassWeavingContext.References.TypeType,
methodWeavingContext.MethodDefinition.GenericParameters.Count))
.Concat(methodWeavingContext.MethodDefinition.Parameters.Select(x => x.ParameterType))
.Concat(methodWeavingContext.MethodDefinition.Parameters
.Where(x => !x.HasCustomAttributes || !x.HasNoKeyAttribute(methodWeavingContext.ClassWeavingContext.References))
.Select(x => x.ParameterType))
.ToList();

tupleTypeReferences.ToList().ForEach(tupleTypeReference => methodWeavingContext.CacheKeyParameterTypes.Add(tupleTypeReference));
Expand Down Expand Up @@ -60,7 +62,8 @@ public static MethodReference GetCacheGetterMethod(ClassWeavingContext classWeav
throw new WeavingException("Cache Property not found or multiple properties found.");
}

MethodReference methodDefinition = classWeavingContext.TypeDefinition.Module.ImportReference(propertyDefinitions.Single().GetMethod);
MethodReference methodDefinition =
classWeavingContext.TypeDefinition.Module.ImportReference(propertyDefinitions.Single().GetMethod);

if (methodDefinition.DeclaringType.GenericParameters.Any())
{
Expand Down Expand Up @@ -95,11 +98,15 @@ public static ILProcessorContext WeaveCreateKey(MethodWeavingContext methodWeavi
.Append(x => x.Create(OpCodes.Call, methodWeavingContext.ClassWeavingContext.References.GetTypeFromHandleMethod));
}

for (int i = 0; i < methodWeavingContext.MethodDefinition.Parameters.Count; i++)
{
int value = i;
int value = 1;

processorContext = processorContext.Append(x => x.Create(OpCodes.Ldarg, value + 1));
foreach (ParameterDefinition parameter in methodWeavingContext.MethodDefinition.Parameters)
{
if (!parameter.HasCustomAttributes || !parameter.HasNoKeyAttribute(methodWeavingContext.ClassWeavingContext.References))
{
processorContext = processorContext.Append(x => x.Create(OpCodes.Ldarg, value));
value++;
}
}

return MemoryCache
Expand Down Expand Up @@ -157,7 +164,8 @@ public static void WeaveSetBeforeReturns(MethodWeavingContext methodWeavingConte
.Append(x => x.Create(OpCodes.Newobj,
methodWeavingContext.ClassWeavingContext.References.NullableTimeSpanConstructor))
.Append(x => x.Create(OpCodes.Callvirt,
methodWeavingContext.ClassWeavingContext.References.MemoryCacheEntryOptionsAbsoluteExpirationRelativeToNowSetter));
methodWeavingContext.ClassWeavingContext.References
.MemoryCacheEntryOptionsAbsoluteExpirationRelativeToNowSetter));
break;

case "SlidingExpiration":
Expand All @@ -168,7 +176,8 @@ public static void WeaveSetBeforeReturns(MethodWeavingContext methodWeavingConte
.Append(x => x.Create(OpCodes.Newobj,
methodWeavingContext.ClassWeavingContext.References.NullableTimeSpanConstructor))
.Append(x => x.Create(OpCodes.Callvirt,
methodWeavingContext.ClassWeavingContext.References.MemoryCacheEntryOptionsSlidingExpirationSetter));
methodWeavingContext.ClassWeavingContext.References
.MemoryCacheEntryOptionsSlidingExpirationSetter));
break;

case "Priority":
Expand Down
5 changes: 5 additions & 0 deletions src/SpatialFocus.MethodCache.Fody/References.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ protected References(ModuleWeaver moduleWeaver)

public TypeReference NoCacheAttributeType { get; set; }

public TypeReference NoKeyAttributeType { get; set; }

public MethodReference NullableTimeSpanConstructor { get; set; }

public MethodReference SetMethod { get; protected set; }
Expand Down Expand Up @@ -69,6 +71,9 @@ public static References Init(ModuleWeaver moduleWeaver)
TypeDefinition cacheAttributeType = moduleWeaver.FindTypeDefinition("SpatialFocus.MethodCache.CacheAttribute");
references.CacheAttributeType = moduleWeaver.ModuleDefinition.ImportReference(cacheAttributeType);

TypeDefinition noKeyAttributeType = moduleWeaver.FindTypeDefinition("SpatialFocus.MethodCache.NoKeyAttribute");
references.NoKeyAttributeType = moduleWeaver.ModuleDefinition.ImportReference(noKeyAttributeType);

TypeDefinition noCacheAttributeType = moduleWeaver.FindTypeDefinition("SpatialFocus.MethodCache.NoCacheAttribute");
references.NoCacheAttributeType = moduleWeaver.ModuleDefinition.ImportReference(noCacheAttributeType);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ public int WithParameter(int a)
{
return a;
}

#pragma warning disable IDE0060 // Remove unused parameter
#pragma warning disable CA1801 // Remove unused parameter
public int WithNoKeyParameter(int a, int b, [NoKey] int c)
{
return a + b;
}
#pragma warning restore IDE0060 // Remove unused parameter
#pragma warning restore CA1801 // Remove unused parameter
#pragma warning restore CA1822 // Mark members as static
}
}
24 changes: 24 additions & 0 deletions src/SpatialFocus.MethodCache.Tests/MemoryCacheKeyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,5 +276,29 @@ public void CacheKeyTest8With15Parameters()
Assert.Equal(14, key[14]);
Assert.Equal(15, key[15]);
}

[Fact]
public void CacheKeyTest9WithNoKeyParameters()
{
using MockMemoryCache mockMemoryCache = MockMemoryCache.Default;

dynamic instance =
TestHelpers.CreateInstance<MemoryCacheKeyTestClass>(MemoryCacheKeyTests.TestResult.Assembly, mockMemoryCache);

dynamic result1 = instance.WithNoKeyParameter(1, 2, 3);
dynamic result2 = instance.WithNoKeyParameter(1, 2, 4);

Assert.Equal(3, result1);
Assert.Equal(3, result2);

Assert.Equal(1, mockMemoryCache.CountSets);
Assert.Equal(2, mockMemoryCache.CountGets);

ITuple key = (ITuple)mockMemoryCache.LastCreatedEntryKey;
Assert.Equal(3, key.Length);
Assert.Equal("SpatialFocus.MethodCache.TestAssembly.MemoryCacheKeyTestClass.WithNoKeyParameter", key[0]);
Assert.Equal(1, key[1]);
Assert.Equal(2, key[2]);
}
}
}
16 changes: 16 additions & 0 deletions src/SpatialFocus.MethodCache/NoKeyAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// <copyright file="NoKeyAttribute.cs" company="Spatial Focus GmbH">
// Copyright (c) Spatial Focus GmbH. All rights reserved.
// </copyright>

namespace SpatialFocus.MethodCache
{
using System;

[AttributeUsage(AttributeTargets.Parameter)]
public sealed class NoKeyAttribute : Attribute
{
public NoKeyAttribute()
{
}
}
}