前面我们已经完成了 CacheInterceptorAttribute 和 RetryInterceptorAttribute。
现在我们打算把这两个拦截器同时应用到同一个方法。
加入一个Log输出
using AspectCore.DynamicProxy;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using System.Text;
namespace Malema.Net;
public class CacheInterceptorAttribute : AbstractInterceptorAttribute
{
public override async Task Invoke(AspectContext context, AspectDelegate next)
{
Console.WriteLine("CacheInterceptor");// 这边新加了一个调试信息
var methodName = context.ImplementationMethod.DeclaringType + context.ImplementationMethod.Name;
var sb = new StringBuilder();
foreach (var item in context.ServiceMethod.GetParameters())
{
sb.Append(item.Name);
}
foreach (var value in context.Parameters)
{
sb.Append(value.GetHashCode());
}
var cacheKey = methodName + sb.ToString();
var cache = context.ServiceProvider.GetService<IMemoryCache>();
var result = await cache.GetOrCreateAsync(cacheKey, async (entry) =>
{
await next(context);
var returnValue = context.ReturnValue;
return returnValue;
});
context.ReturnValue = result;
}
}
修改一个前面用到的测试类 TestService
namespace Malema.Net;
public interface ITestService
{
string TestCache(int age);
}
namespace Malema.Net;
public class TestService : ITestService
{
// cache在上面所以 cache会优先执行.
[CacheInterceptor]
[RetryInterceptor(3)]
public string TestCache(int age)
{
Console.WriteLine("TestCache");
return (age + 100).ToString();
}
}
using Malema.Net;
using Microsoft.Extensions.DependencyInjection;
var sp = DIConfig.GetServiceProvider();
var service = sp.GetService<ITestService>();
service.TestCache(30);
Console.WriteLine("--------------------------");
var name2 = service.TestCache(30);
Console.WriteLine("done" + name2);
Console.ReadKey();
输出
CacheInterceptor
Retry
TestCache
--------------------------
CacheInterceptor
done130
我们会发现 第二次调用函数的时候少了一个 Retry。 说明到Cache这个拦截器就直接把值给返回了。
符合我们程序想要的行为。
AspectCore也提供了一个属性 Order来控制优先级。 如下的代码。 值越小越优先。 输出的内容跟上面的代码是一样的
namespace Malema.Net;
public class TestService : ITestService
{
[CacheInterceptor(Order = 1)]
[RetryInterceptor(3, Order = 2)]
public string TestCache(int age)
{
Console.WriteLine("TestCache");
return (age + 100).ToString();
}
}
完整的代码在https://gitee.com/malema/Examples/tree/AspectCore%2FTwo-Interceptor/AspectCore-Example这边可以看到 可以用下面的git命令把代码签出到本地
git clone https://gitee.com/malema/Examples
git checkout AspectCore/Two-Interceptor