AspectCore 两个拦截器 two interceptor

前面我们已经完成了 CacheInterceptorAttribute 和 RetryInterceptorAttribute。

现在我们打算把这两个拦截器同时应用到同一个方法。

修改一下 CacheInterceptorAttribute

加入一个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();
    }
}

Program.cs


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这个拦截器就直接把值给返回了。

符合我们程序想要的行为。

执行顺序 Order属性

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
最近更新的
...