Filter --ResourceFilter --ActionFilter - 做aop

1.Authorize
2.ResourceFilter
3.ActionFilter
4.Result
5.AlwaysRunResult
6.Exception

只要是框架提供给我们的是接口、抽象类,天生就是为了让我我们来扩展的

1 ResourceFilter    就是做缓存用的       接口IResourceFilter  IAsyncResourceFilter

执行顺序     就是用OnResourceExecuting 和 OnResourceExecuted 方法把控制器的构造函数+action给包裹起来了
       ResourceFilter也有AsyncResourceFilter    ---执行结果和同步版本是一致的;

正常的顺序是  :   控制器的构造函数——————》自己写的方法action————》完成

加上  [CustomResourceFilter] 特性以后   执行顺序:   OnResourceExecuting————》   控制器的构造函数——————》自己写的方法action————》OnResourceExecuted———》完成

写async 版本的ResourceFilter    把路径缓存下来

    public class CustomAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter
    {
        //ResourceFilter 就是为了做缓存用的  
        private static Dictionary<string, object> CacheDictionary = new Dictionary<string, object>();

        /// <summary>
        /// 在资源执行的时候
        /// 
        /// 扩展缓存:
        /// 1.一组数据保存在内存中
        /// 2.存储数据的标识---存数据---把标识附上去,取数据也可以通过这个标识直接去去
        /// 3.缓存有数据,且标识不变---取到的缓存数据也不变
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            {
                Console.WriteLine("OnResourceExecutionAsync OnResourceExecutingAsync");   // action执行前就发生
            }
            string key = context.HttpContext.Request.Path;
            //在这里就应该检查缓存     可以检查redis
            //1.如果有缓存,就应该直接响应给前端了,不再继续往后,如果没有--就执行next.Invoke();
            if (CacheDictionary.ContainsKey(key))
            {
                object oResult = CacheDictionary[key];
                context.Result = (IActionResult)oResult;// context.Result 类似于一个断路器,只要对context.Result赋值,就不再继续往后执行了
            }
            else {
                ResourceExecutedContext executedContext= await next.Invoke();   // action执行
                CacheDictionary[key] = executedContext.Result;
            }


           // await next.Invoke();  // action执行

           
            {
                Console.WriteLine("OnResourceExecutionAsync ResourceExecuted");    // action完成后发生
            }
        }
    }

  ResourceFilter 的全局注册

  public void ConfigureServices(IServiceCollection services)
        {
            //services.AddControllersWithViews();
            #region 全局注册Filter
            services.AddControllersWithViews(
                option =>
                {
                    option.Filters.Add<CustomResourceFilterAttribute>();   //全局注册CustomResourceFilterAttribute
                }
            ).AddControllersAsServices();
            #endregion
        }

  全局   控制器  action  全部都注册以后的执行顺序   

1全局:OnResourceExecuting                           外
2控制器类:OnResourceExecuting       中  
3Action方法:OnResourceExecuting           里
4开始实例化控制器                    核心
5开始执行Action方法              核心 
6Action方法上的:OnResourceExecuted      里
7控制器类:OnResourceExecuted        中 
8全局:OnResourceExecuted          

2ActionFilter    IActionFilter  IAsyncActionFilter  ActionFilterAttribute       最适合做日志

执行顺序

 

1.实例化控制器
2.执行CustomActionFilterAttribute.------OnActionExecuting
3.执行action方法
4.执行CustomActionFilterAttribute--------OnActionExecuted   

  actionFilter 在你检查OnActionExecuting时候 已经实例化类了,所以不适合做缓存,     

 

posted @ 2022-02-15 17:23  wolfsocket  阅读(90)  评论(0编辑  收藏  举报