diff --git a/src/SpatialFocus.MethodCache.Fody/Extensions/ParameterDefinitionExtension.cs b/src/SpatialFocus.MethodCache.Fody/Extensions/ParameterDefinitionExtension.cs
new file mode 100644
index 0000000..8efb3ab
--- /dev/null
+++ b/src/SpatialFocus.MethodCache.Fody/Extensions/ParameterDefinitionExtension.cs
@@ -0,0 +1,31 @@
+//
+// Copyright (c) Spatial Focus GmbH. All rights reserved.
+//
+
+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));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SpatialFocus.MethodCache.Fody/MemoryCache.cs b/src/SpatialFocus.MethodCache.Fody/MemoryCache.cs
index 6b1880e..3f890cd 100644
--- a/src/SpatialFocus.MethodCache.Fody/MemoryCache.cs
+++ b/src/SpatialFocus.MethodCache.Fody/MemoryCache.cs
@@ -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));
@@ -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())
{
@@ -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
@@ -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":
@@ -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":
diff --git a/src/SpatialFocus.MethodCache.Fody/References.cs b/src/SpatialFocus.MethodCache.Fody/References.cs
index bc1367f..feb9b8e 100644
--- a/src/SpatialFocus.MethodCache.Fody/References.cs
+++ b/src/SpatialFocus.MethodCache.Fody/References.cs
@@ -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; }
@@ -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);
diff --git a/src/SpatialFocus.MethodCache.TestAssembly/MemoryCacheKeyTestClass.cs b/src/SpatialFocus.MethodCache.TestAssembly/MemoryCacheKeyTestClass.cs
index 77c09ab..038a76b 100644
--- a/src/SpatialFocus.MethodCache.TestAssembly/MemoryCacheKeyTestClass.cs
+++ b/src/SpatialFocus.MethodCache.TestAssembly/MemoryCacheKeyTestClass.cs
@@ -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
}
}
\ No newline at end of file
diff --git a/src/SpatialFocus.MethodCache.Tests/MemoryCacheKeyTests.cs b/src/SpatialFocus.MethodCache.Tests/MemoryCacheKeyTests.cs
index 2652ea3..bc615fe 100644
--- a/src/SpatialFocus.MethodCache.Tests/MemoryCacheKeyTests.cs
+++ b/src/SpatialFocus.MethodCache.Tests/MemoryCacheKeyTests.cs
@@ -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(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]);
+ }
}
}
\ No newline at end of file
diff --git a/src/SpatialFocus.MethodCache/NoKeyAttribute.cs b/src/SpatialFocus.MethodCache/NoKeyAttribute.cs
new file mode 100644
index 0000000..d355793
--- /dev/null
+++ b/src/SpatialFocus.MethodCache/NoKeyAttribute.cs
@@ -0,0 +1,16 @@
+//
+// Copyright (c) Spatial Focus GmbH. All rights reserved.
+//
+
+namespace SpatialFocus.MethodCache
+{
+ using System;
+
+ [AttributeUsage(AttributeTargets.Parameter)]
+ public sealed class NoKeyAttribute : Attribute
+ {
+ public NoKeyAttribute()
+ {
+ }
+ }
+}
\ No newline at end of file