Skip to content

Commit

Permalink
Merge pull request #11 from catcherwong/dev
Browse files Browse the repository at this point in the history
Improving evict operation for Caching Interceptor.
  • Loading branch information
catcherwong authored Feb 6, 2018
2 parents c219819 + de0bc9a commit 20e440c
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 59 deletions.
51 changes: 40 additions & 11 deletions src/EasyCaching.Core/DefaultEasyCachingKeyGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,38 @@ public string GetCacheKey(MethodInfo methodInfo, object[] args, string prefix)
}
}

/// <summary>
/// Gets the cache key prefix.
/// </summary>
/// <returns>The cache key prefix.</returns>
/// <param name="methodInfo">Method info.</param>
/// <param name="prefix">Prefix.</param>
public string GetCacheKeyPrefix(MethodInfo methodInfo, string prefix)
{
if (string.IsNullOrWhiteSpace(prefix))
{
var typeName = methodInfo.DeclaringType.Name;
var methodName = methodInfo.Name;

return this.GenerateCacheKeyPrefix(typeName, methodName);
}
else
{
return this.GenerateCacheKeyPrefix(string.Empty, prefix);
}
}

/// <summary>
/// Generates the cache key prefix.
/// </summary>
/// <returns>The cache key prefix.</returns>
/// <param name="first">First.</param>
/// <param name="second">Second.</param>
private string GenerateCacheKeyPrefix(string first, string second)
{
return string.Concat(first,_linkChar,second,_linkChar).TrimStart(_linkChar);
}

/// <summary>
/// Formats the arguments to part of cache key.
/// </summary>
Expand Down Expand Up @@ -72,25 +104,22 @@ private string GenerateCacheKey(string typeName, string methodName, IList<string
{
var builder = new StringBuilder();

builder.Append(typeName);
builder.Append(_linkChar);

builder.Append(methodName);
builder.Append(_linkChar);
builder.Append(this.GenerateCacheKeyPrefix(typeName,methodName));

foreach (var param in parameters)
{
builder.Append(param);
builder.Append(_linkChar);
}

var str = builder.ToString().TrimStart(_linkChar).TrimEnd(_linkChar);
var str = builder.ToString().TrimEnd(_linkChar);

using (SHA1 sha1 = SHA1.Create())
{
byte[] data = sha1.ComputeHash(Encoding.UTF8.GetBytes(str));
return Convert.ToBase64String(data, Base64FormattingOptions.None);
}
return str;
//using (SHA1 sha1 = SHA1.Create())
//{
// byte[] data = sha1.ComputeHash(Encoding.UTF8.GetBytes(str));
// return Convert.ToBase64String(data, Base64FormattingOptions.None);
//}
}

/// <summary>
Expand Down
9 changes: 8 additions & 1 deletion src/EasyCaching.Core/IEasyCachingKeyGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
/// </summary>
public interface IEasyCachingKeyGenerator
{

/// <summary>
/// Gets the cache key.
/// </summary>
Expand All @@ -16,5 +15,13 @@ public interface IEasyCachingKeyGenerator
/// <param name="args">Arguments.</param>
/// <param name="prefix">Prefix.</param>
string GetCacheKey(MethodInfo methodInfo, object[] args, string prefix);

/// <summary>
/// Gets the cache key prefix.
/// </summary>
/// <returns>The cache key prefix.</returns>
/// <param name="methodInfo">Method info.</param>
/// <param name="prefix">Prefix.</param>
string GetCacheKeyPrefix(MethodInfo methodInfo, string prefix);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,13 @@ public class EasyCachingPutAttribute : EasyCachingInterceptorAttribute
public class EasyCachingEvictAttribute : EasyCachingInterceptorAttribute
{
/// <summary>
/// Gets or sets a value indicating whether evict all cached values which are
/// Gets or sets a value indicating whether evict all cached values by cachekey prefix
/// </summary>
/// <value><c>true</c> if all; otherwise, <c>false</c>.</value>
public bool All { get; set; } = false;
/// <remarks>
/// This need to use with CacheKeyPrefix.
/// </remarks>
/// <value><c>true</c> if is all; otherwise, <c>false</c>.</value>
public bool IsAll { get; set; } = false;

/// <summary>
/// Gets or sets a value indicating whether is before.
Expand Down
23 changes: 17 additions & 6 deletions src/EasyCaching.Interceptor.AspectCore/EasyCachingInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private async Task ProceedAbleAsync(AspectContext context, AspectDelegate next)
// Invoke the method if we don't have a cache hit
await next(context);

if (!string.IsNullOrWhiteSpace(cacheKey))
if (!string.IsNullOrWhiteSpace(cacheKey) && context.ReturnValue != null)
await CacheProvider.SetAsync(cacheKey, context.ReturnValue, TimeSpan.FromSeconds(attribute.Expiration));
}
}
Expand All @@ -92,7 +92,7 @@ private async Task ProcessPutAsync(AspectContext context)
{
var attribute = context.ServiceMethod.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(EasyCachingPutAttribute)) as EasyCachingPutAttribute;

if (attribute != null)
if (attribute != null && context.ReturnValue != null)
{
var cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters,attribute.CacheKeyPrefix);

Expand All @@ -111,11 +111,22 @@ private async Task ProcessEvictAsync(AspectContext context, bool isBefore)
var attribute = context.ServiceMethod.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(EasyCachingEvictAttribute)) as EasyCachingEvictAttribute;

if (attribute != null && attribute.IsBefore == isBefore)
{
var cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix);
{
if(attribute.IsAll)
{
//If is all , clear all cached items which cachekey start with the prefix.
var cachePrefix = KeyGenerator.GetCacheKeyPrefix(context.ServiceMethod, attribute.CacheKeyPrefix);

await CacheProvider.RemoveAsync(cacheKey);
await CacheProvider.RemoveByPrefixAsync(cachePrefix);
}
else
{
//If not all , just remove the cached item by its cachekey.
var cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix);

await CacheProvider.RemoveAsync(cacheKey);
}
}
}
}
}
}
21 changes: 16 additions & 5 deletions src/EasyCaching.Interceptor.Castle/EasyCachingInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private void ProceedAble(IInvocation invocation)
// Invoke the method if we don't have a cache hit
invocation.Proceed();

if (!string.IsNullOrWhiteSpace(cacheKey))
if (!string.IsNullOrWhiteSpace(cacheKey) && invocation.ReturnValue != null)
_cacheProvider.Set(cacheKey, invocation.ReturnValue, TimeSpan.FromSeconds(attribute.Expiration));
}
}
Expand All @@ -98,7 +98,7 @@ private void ProcessPut(IInvocation invocation)

var attribute = serviceMethod.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(EasyCachingPutAttribute)) as EasyCachingPutAttribute;

if (attribute != null)
if (attribute != null && invocation.ReturnValue != null)
{
var cacheKey = _keyGenerator.GetCacheKey(serviceMethod, invocation.Arguments, attribute.CacheKeyPrefix);

Expand All @@ -118,10 +118,21 @@ private void ProcessEvict(IInvocation invocation, bool isBefore)
var attribute = serviceMethod.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(EasyCachingEvictAttribute)) as EasyCachingEvictAttribute;

if (attribute != null && attribute.IsBefore == isBefore)
{
var cacheKey = _keyGenerator.GetCacheKey(serviceMethod, invocation.Arguments, attribute.CacheKeyPrefix);
{
if(attribute.IsAll)
{
//If is all , clear all cached items which cachekey start with the prefix.
var cacheKeyPrefix = _keyGenerator.GetCacheKeyPrefix(serviceMethod, attribute.CacheKeyPrefix);

_cacheProvider.Remove(cacheKey);
_cacheProvider.RemoveByPrefix(cacheKeyPrefix);
}
else
{
//If not all , just remove the cached item by its cachekey.
var cacheKey = _keyGenerator.GetCacheKey(serviceMethod, invocation.Arguments, attribute.CacheKeyPrefix);

_cacheProvider.Remove(cacheKey);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ public void Generate_CacheKey_With_No_Params_Method_Should_Succeed()
var methodName = "Method1";
MethodInfo methodInfo = typeof(Demo).GetMethod(methodName);

var key = _keyGenerator.GetCacheKey(methodInfo, new object[]{} ,string.Empty);
var key = _keyGenerator.GetCacheKey(methodInfo, new object[] { }, string.Empty);

var keyBeforeHash = $"Demo:Method1:0";

Assert.Equal(SHA1AndBase64(keyBeforeHash),key);
Assert.Equal($"Demo:Method1:0", key);
}

[Fact]
Expand All @@ -38,9 +36,7 @@ public void Generate_CacheKey_With_No_Params_And_Prefix_Method_Should_Succeed()

var key = _keyGenerator.GetCacheKey(methodInfo, new object[] { }, "GenKey");

var keyBeforeHash = $"GenKey:0";

Assert.Equal(SHA1AndBase64(keyBeforeHash), key);
Assert.Equal($"GenKey:0", key);
}

[Fact]
Expand All @@ -49,11 +45,9 @@ public void Generate_CacheKey_With_Int_Param_Method_Should_Succeed()
var methodName = "Method2";
MethodInfo methodInfo = typeof(Demo).GetMethod(methodName);

var key = _keyGenerator.GetCacheKey(methodInfo, new object[] { 10 } ,string.Empty);

var keyBeforeHash = $"Demo:Method2:10";
var key = _keyGenerator.GetCacheKey(methodInfo, new object[] { 10 }, string.Empty);

Assert.Equal(SHA1AndBase64(keyBeforeHash), key);
Assert.Equal($"Demo:Method2:10", key);
}

[Fact]
Expand All @@ -64,9 +58,7 @@ public void Generate_CacheKey_With_Int_Param_And_Prefix_Method_Should_Succeed()

var key = _keyGenerator.GetCacheKey(methodInfo, new object[] { 10 }, "GenKey");

var keyBeforeHash = $"GenKey:10";

Assert.Equal(SHA1AndBase64(keyBeforeHash), key);
Assert.Equal($"GenKey:10", key);
}

[Fact]
Expand All @@ -75,11 +67,9 @@ public void Generate_CacheKey_With_String_Param_Method_Should_Succeed()
var methodName = "Method3";
MethodInfo methodInfo = typeof(Demo).GetMethod(methodName);

var key = _keyGenerator.GetCacheKey(methodInfo, new object[]{ "str" } ,string.Empty);

var keyBeforeHash = $"Demo:Method3:str";
var key = _keyGenerator.GetCacheKey(methodInfo, new object[] { "str" }, string.Empty);

Assert.Equal(SHA1AndBase64(keyBeforeHash), key);
Assert.Equal($"Demo:Method3:str", key);
}

[Fact]
Expand All @@ -90,9 +80,7 @@ public void Generate_CacheKey_With_String_Param_And_Prefix_Method_Should_Succeed

var key = _keyGenerator.GetCacheKey(methodInfo, new object[] { "str" }, "GenKey");

var keyBeforeHash = $"GenKey:str";

Assert.Equal(SHA1AndBase64(keyBeforeHash), key);
Assert.Equal($"GenKey:str", key);
}

[Fact]
Expand All @@ -103,9 +91,7 @@ public void Generate_CacheKey_With_DateTime_Param_Method_Should_Succeed()

var key = _keyGenerator.GetCacheKey(methodInfo, null, string.Empty);

var keyBeforeHash = $"Demo:Method4:0";

Assert.Equal(SHA1AndBase64(keyBeforeHash), key);
Assert.Equal($"Demo:Method4:0", key);
}

[Fact]
Expand All @@ -116,9 +102,7 @@ public void Generate_CacheKey_With_DateTime_Param_And_Prefix_Method_Should_Succe

var key = _keyGenerator.GetCacheKey(methodInfo, null, "GenKey");

var keyBeforeHash = $"GenKey:0";

Assert.Equal(SHA1AndBase64(keyBeforeHash), key);
Assert.Equal($"GenKey:0", key);
}

[Fact]
Expand All @@ -129,9 +113,7 @@ public void Generate_CacheKey_With_ICachable_Param_Method_Should_Succeed()

var key = _keyGenerator.GetCacheKey(methodInfo, new object[] { new Product() }, string.Empty);

var keyBeforeHash = $"Demo:Method5:1000";

Assert.Equal(SHA1AndBase64(keyBeforeHash), key);
Assert.Equal($"Demo:Method5:1000", key);
}

[Fact]
Expand All @@ -142,9 +124,29 @@ public void Generate_CacheKey_With_ICachable_Param_And_Prefix_Method_Should_Succ

var key = _keyGenerator.GetCacheKey(methodInfo, new object[] { new Product() }, "GenKey");

var keyBeforeHash = $"GenKey:1000";
Assert.Equal($"GenKey:1000", key);
}

[Fact]
public void Generate_CacheKeyPrefix_Without_PrefixParam_Should_Succeed()
{
var methodName = "Method3";
MethodInfo methodInfo = typeof(Demo).GetMethod(methodName);

var key = _keyGenerator.GetCacheKeyPrefix(methodInfo, string.Empty);

Assert.Equal($"Demo:Method3:", key);
}

[Fact]
public void Generate_CacheKeyPrefix_With_PrefixParam_Should_Succeed()
{
var methodName = "Method3";
MethodInfo methodInfo = typeof(Demo).GetMethod(methodName);

var key = _keyGenerator.GetCacheKeyPrefix(methodInfo, "prefix");

Assert.Equal(SHA1AndBase64(keyBeforeHash), key);
Assert.Equal($"prefix:", key);
}

private string SHA1AndBase64(string str)
Expand Down Expand Up @@ -173,4 +175,4 @@ public class Product : ICachable
}

}
}
}
16 changes: 16 additions & 0 deletions test/EasyCaching.UnitTests/Infrastructure/IExampleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ public interface ICastleExampleService
string PutTest(int num,string str = "123");

string EvictTest();

string EvictAllTest();
}

public class CastleExampleService : ICastleExampleService, IEasyCaching
{
[EasyCachingEvict(CacheKeyPrefix = "CastleExample",IsAll = true)]
public string EvictAllTest()
{
return "EvictAllTest";
}

[EasyCachingEvict(CacheKeyPrefix = "CastleExample")]
public string EvictTest()
{
Expand Down Expand Up @@ -50,12 +58,20 @@ public interface IAspectCoreExampleService : IEasyCaching
[EasyCachingEvict(CacheKeyPrefix = "AspectCoreExample")]
string EvictTest();

[EasyCachingEvict(CacheKeyPrefix = "AspectCoreExample",IsAll = true)]
string EvictAllTest();

[EasyCachingPut(CacheKeyPrefix = "AspectCoreExample")]
string PutTest(int num , string str="123");
}

public class AspectCoreExampleService : IAspectCoreExampleService
{
public string EvictAllTest()
{
return "EvictAllTest";
}

public string EvictTest()
{
return "EvictTest";
Expand Down
Loading

0 comments on commit 20e440c

Please sign in to comment.