aspnetcore中的过滤器是Aop编程的一种实现形式。记录下学习的过程,方便以后查阅

# ResourceFilter 同步实现

我们新建一个 WebApi 项目,然后创建一个自定义实现的 ResourceFilter (资源过滤器)

public class CustomResourceFilterAttribute : Attribute, IResourceFilter
    {
        // 资源进入之前
        public void OnResourceExecuting (ResourceExecutingContext context)
        {
            Console.WriteLine ("请求之前");
        }
        // 资源退出之后
        public void OnResourceExecuted (ResourceExecutedContext context)
        {
            Console.WriteLine ("请求之后");
        }
    }

上面自定义的资源过滤器继承了特性和实现了资源过滤器的接口

# 总结

在框架中凡是系统提供的接口都是给开发者做扩展使用的
实现完自定义的资源过滤器后,将他们标注在相关的 action 上面

[Route ("/api/[action]")]
public class ResourceController : ControllerBase
{
      private readonly ILogger<ResourceController> _logger;
      public ResourceController (ILogger<ResourceController> logger)
      {
          _logger = logger;
          Console.WriteLine ("构造函数");
      }
      [HttpGet]
      [CustomResourceFilter]
      public string ResourceIndex ()
      {
          Console.WriteLine ("方法执行中");
          return "success";
      }
}

# 运行项目

# 结论

OnResourceExecuting-》控制器构造函数-》调用的API(action)-》OnResourceExecuted

# ResourceFilter 异步实现

同步和异步原理和步骤上是一样的,书写的代码有所不同.

public class CustomAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter
    {
        public async Task OnResourceExecutionAsync (ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            Console.WriteLine ("执行之前 Async");
            ResourceExecutedContext resource = await next.Invoke ();
            Console.WriteLine ("执行之后 Async");
        }
    }
[Route ("/api/[action]")]
public class ResourceController : ControllerBase
{
     private readonly ILogger<ResourceController> _logger  
     public ResourceController (ILogger<ResourceController> logger)
     {
         _logger = logger;
         Console.WriteLine ("构造函数");
       
     [HttpGet]
     [CustomAsyncResourceFilterAttribute]
     public string ResourceAsyncIndex () 
     {
         Console.WriteLine ("方法执行中");
         return "success";
     }
}

# ResourceFilter 在业务上能用来做什么

缓存

下面实现缓存的代码以异步实现

public class CustomAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter
    {
        public async Task OnResourceExecutionAsync (ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            Console.WriteLine ("执行之前 Async");
            string requestPath = context.HttpContext.Request.Path;
            bool sign = await RedisHelper.Do (d => d.KeyExistsAsync (requestPath));
            if (sign)
            {
                string  value = await RedisHelper.StringGetAsync (requestPath);
                // 类似于短路。context.Result 赋值后就会终止
                context.Result = new JsonResult (value);
            }
            else
            {
                // 获取 action 中的结果
                ResourceExecutedContext resource = await next.Invoke ();
                dynamic Result = resource.Result;
                // 缓存 20 秒
                await RedisHelper.StringSetAsync (requestPath, Result.Value, TimeSpan.FromSeconds (20));
                string value = await RedisHelper.StringGetAsync (requestPath);
                Console.WriteLine (value);
            }
            Console.WriteLine ("执行之后 Async");
        }
    }

上面 RedisHelper 的操作类库是自己封装了一下,方便调用。redis 的 nuget 地址如果服务器还没有过期