zl程序教程

您现在的位置是:首页 >  其他

当前栏目

.Net6对AOP的多种支持之IAsyncResourceFilter

2023-04-18 15:22:39 时间

 

环境:.Net6 Web项目 Mvc结构

开发工具: VS2022

IAsyncResourceFilter(资源缓存异步)

IAsyncResourceFilter扩展

   ASP.NET Core6提供的是接口IAsyncResourceFilter

   必须是自定义扩展 通过一个特性的支持

作用是做异步缓存

 

执行顺序

  实现的接口里有个委托参数,执行这个委托(就是执行构造方法和Action方法),所以需要以这个委托执行为界限,可在之前或者之后添加

需要执行的。

 

缓存构造步骤

     1定义一个缓存区域

     2请求过来后进行判断,如果有缓存返回缓存里的值,如果没有缓存则进行处理

     3把处理的结果加入缓存中

 

实现IAsyncResourceFilter

1定义特性类

       名称以Attribute结尾(标记特性时可以省略),继承Attribute、IAsyncResourceFilter(并实现该接口)

         public class CustomCacheAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter

 

2定义静态字典做缓存

             private static Dictionary<string, object> _dictionary = new Dictionary<string, object>();

3 判断缓存

   判断缓存中是否有key,如果有将值取出值

       string key = context.HttpContext.Request.Path;

            if (_dictionary.ContainsKey(key))

            {

                context.Result =(IActionResult) _dictionary[key];

            }

   如果没有值,则将值加入到缓存中去

 else

            {

                //next是一个委托,执行委托Invoke();

                //查看委托的返回类型为Task<ResourceExecutedContext>

                // Task<ResourceExecutedContext> resource = next.Invoke();

 

                //异步的时候,建设使用 async +await,

                ResourceExecutedContext resource = await next.Invoke();//这句话的执行就是去执行控制器的构造函数+Action方法

                if (resource.Result!=null)

                {

                    _dictionary[key] = resource.Result;

                }

 

            }

 

完整代码示例

特性类

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace WebApplication1.Untity.Filters
{
    /// <summary>
    /// 使用特性进行扩展,实现IAsyncResourceFilter接口
    /// </summary>

    public class CustomCacheAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter
    {
        //1定义一个缓存区域
        //2请求过来后进行判断,如果有缓存返回缓存里的值,如果没有缓存则进行处理
        //3把处理的结果加入缓存中

        private static Dictionary<string, object> _dictionary = new Dictionary<string, object>();

        public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        {

            Console.WriteLine("CustomCacheAsyncResourceFilterAttribute.OnResourceExecutionAsync Before");

            string key = context.HttpContext.Request.Path;
            //在xx资源之前
            if (_dictionary.ContainsKey(key))
            {
                context.Result =(IActionResult) _dictionary[key];
            }
            else
            {
                //next是一个委托,执行委托Invoke();
                //查看委托的返回类型为Task<ResourceExecutedContext>
                // Task<ResourceExecutedContext> resource = next.Invoke();

                //异步的时候,建设使用 async +await,
                ResourceExecutedContext resource = await next.Invoke();//这句话的执行就是去执行控制器的构造函数+Action方法
                //在xx资源之后
                if (resource.Result!=null)
                {
                    _dictionary[key] = resource.Result;
                }

            }


       
            Console.WriteLine("CustomCacheAsyncResourceFilterAttribute.OnResourceExecutionAsync After");

        }
    }
}

 

Action

        [CustomCacheAsyncResourceFilter]
        public IActionResult Index2() 
        {
            {
                //此处是处理的业务逻辑,或返回的处理结果 省略..........
            }
            ViewBag.Date = DateTime.Now.ToString("yyyy-MM-dd ss");
            return View();
        }

前端

@{
    ViewData["Title"] = "Index2";
}

<h1>Index2</h1>
<h3>来自于控制器的计算结果:@ViewBag.Date</h3>
<h3>视图中实际计算的结果:@DateTime.Now.ToString("yyyy-MM-dd   ss")</h3>