7 Aop 上手练习 (1 ResourceFilter)(.net 上手笔记 )

77 阅读1分钟

一 基础概念。

当一个通用的新需求产生时(异常处理,加日志)

普通方法 。
1 大量重复代码 ,
2 大量测试
3 违背开闭原则

AOP 不修改代码的前提下,可以动态的增加业务逻辑 。

2 .net core中的aop [6种]

1 AuthrizeAtrribute 权限验证

2 IResourceFilter 资源缓存

3 IActionFilter 方法前后

4 IResultFilter 结果生成前后。

5 IAlwaysRun 响应结果的补充

6 IExceptionFilter 异常处理。

二 第一个例子。IResourceFilter

1 创建文件 Utils/Filters/MyResourceFilter.cs

using Microsoft.AspNetCore.Mvc.Filters;

namespace p7.Utils.Filters
{
    public class MyResourceFilter : Attribute, IResourceFilter
    {
   
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            Console.WriteLine("MyResourceFilter.OnResourceExecuting");
        }

        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            Console.WriteLine("MyResourceFilter.OnResourceExecuted");
        }

    }
}

2 控制器使用属性。

using Microsoft.AspNetCore.Mvc;
using p7.Models;
using p7.Utils.Filters;
using System.Diagnostics;

namespace p7.Controllers
{
    public class HomeController : Controller
    {
          
        [MyResourceFilter]
        public IActionResult Index()
        {
            return View();
        }

      
    }
}

执行效果 。 image.png

3 缓存控制器的内容


        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            string key = context.HttpContext.Request.Path;
            if (CacheDict.ContainsKey(key)) {
                context.Result = (IActionResult)CacheDict[key];
            }
        }



        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            string key = context.HttpContext.Request.Path;
            CacheDict[key] = context.Result;
        }

控制器,和视图代码 。


        [MyResourceFilter]
        public IActionResult Index()
        {
            ViewBag.date = DateTime.Now.ToString("yyyy-MM-dd ss");
            return View();
        }

//视图中代码 。
<h2>ViewBag 中的内容 @ViewBag.date</h2>
<h2>实际计算 中的内容 @DateTime.Now.ToString("yyyy-MM-dd ss")</h2>


image.png

来个异步的实现例子。

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

namespace p7.Utils.Filters
{
    public class MyResourceFilter2 : Attribute, IAsyncResourceFilter
    {

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

        public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            Console.WriteLine("OnResourceExecutionAsync start");


            string key = context.HttpContext.Request.Path;
            if (CacheDict.ContainsKey(key))
            {
                context.Result = (IActionResult)CacheDict[key];
            } else
            {
                ResourceExecutedContext resource = await next.Invoke();
                CacheDict[key] = resource.Result;

             }
        }
    }
}

使用方法一样。在控制器内添加属性。

image.png

使用场景

天生适合做缓存。