.netCore的AOP详解(一)

185 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

前言

从今天开始,我们开启.netcore的文章更新,我们都知道现在.netcore的重要性,而我今天要讲的是面向切面编程AOP,我们一起来看一看吧。

AOP的背景

项目已经上线—且正常运行产品经理—来个新需求

image-20211130165928663

普通方式解决:

()面向切面编程AOP

Aspect Oriented Programming在不修改之前的代码为基础,可以动态的增加业务逻辑:

如果可以在已经成型的程序中,如果可以动态在某些行为之前增加点内容;在某些行为之后增加点内容 之前已经开发好的内容保持不变;


ASP.NETCore中的AOP--Filter

AuthorizeAttribute

IResourceFilter

IActionFilter

IResultFilter

IAlwaysRun

IExceptionFilter

AOPIResourceFilter 扩展

ASP.NET Core6提供的是接口IResourceFilter

必须是自定义扩展

通过一个特性的支持

开始实操 ---扩展

执行顺序

IResourceFilter场景应用

天生就是为了缓存而生的

扩展支持缓存

为什么说天生就是为了缓存而生的?

举例代码:

​
​
//customAttrubite.cs
​
​
        //public void OnResourceExecuting(ResourceExecutingContext context)
        //{
​
        //    string key = context.HttpContext.Request.Path;
        //    if (dictionary.ContainsKey(key))
        //    {
        //        //只要缓存中有,不往下执行,就直接返回给回调方
        //        context.Result = (IActionResult)dictionary[key];
        //    }
        //    Console.WriteLine(context.Result);
​
        //}
​
        //public void OnResourceExecuted(ResourceExecutedContext context)
        //{
        //    string key = context.HttpContext.Request.Path;
        //    dictionary[key] = context.Result;
        //    Console.WriteLine(context.Result);
        //}
​
​
​
     // FirstController.cs
​
  public FirstController(ILogger<FirstController>logger, ILoggerFactory loggerFactory)
        {
            this._logger = logger;
            this._logger.LogInformation($"(this.GetType().Name)被构造了111");
            this._loggerFactory = loggerFactory;
            ILogger<FirstController> logger2= loggerFactory.CreateLogger<FirstController>();
            logger2.LogInformation($"(this.GetType().Name)被构了222");
        }
​
​
[custom]
。。。
    

IAsyncResourceFilter扩展应用

ASP.NET Core6提供的是接口IAsyncResourceFilter

必须是自定义扩展

开始实操 ---扩展

执行顺序

//      public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        //      {
        //          string key = context.HttpContext.Request.Path;
        //          if (dictionary.ContainsKey(key))
        //          {
        //              //只要缓存中有,不往下执行,就直接返回给回调方
        //              context.Result = (IActionResult)dictionary[key];
        //              Console.WriteLine(context.Result);
        //          }
        //          else {

        //ResourceExecutedContext resource = await next.Invoke();
        //          }
        

AOP-IActionFilter扩展

ASP.NET Core6提供的是接口IActionFilter/ActionFilterAttribute

可以自定义扩展也可以直接使用

通过一个特性的支持

开始实操 ---扩展

执行顺序

*ActionFilter场景应用

适合做什么呢? 缓存? 缓存可以做---不适合 为什么呢?下个视频专门对比特点:更加靠近Action 记录的就是在Action执行前后最真实的参数和结果;

适合写日志

代码:

​
​
//customAtrribute.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
​
namespace 练习Demo.Unity.Filter
{
    public class CustomResourceAttribute : Attribute,IActionFilter
​
    {
        private readonly ILogger<CustomResourceAttribute> _logger;
        public CustomResourceAttribute(ILogger<CustomResourceAttribute> logger)
        {
            this._logger = logger;
        }
​
        private static Dictionary<string,object> dictionary = new Dictionary<string,object>();
       
​
        public void OnActionExecuting(ActionExecutingContext context)
        {
            var param = context.HttpContext.Request.QueryString.Value;
            var controller = context.HttpContext.GetRouteValue("controller");
            var actionName = context.HttpContext.GetRouteValue("action");
            _logger.LogInformation($"控制器{controller},方法{actionName},参数{param}");  
        }
​
        public void OnActionExecuted(ActionExecutedContext context)
        {
            var result = Newtonsoft.Json.JsonConvert.SerializeObject(context.Result);
            var controller = context.HttpContext.GetRouteValue("controller");
            var actionName = context.HttpContext.GetRouteValue("action");
            _logger.LogInformation($"控制器{controller},方法{actionName},结果{result}");
        }
​
    
    }
}
​
​
//FirstController.cs
using Microsoft.AspNetCore.Mvc;
using 练习Demo.Unity.Filter;
​
namespace 练习Demo.Controllers
{
    public class FirstController : Controller
    {
        private readonly ILogger<FirstController> _logger;
        private readonly ILoggerFactory _loggerFactory;
​
​
        //构造函数  ILogger 是日志记录器
        public FirstController(ILogger<FirstController>logger, ILoggerFactory loggerFactory)
        {
            this._logger = logger;
            this._logger.LogInformation($"(this.GetType().Name)被构造了111");
            this._loggerFactory = loggerFactory;
            ILogger<FirstController> logger2= loggerFactory.CreateLogger<FirstController>();
            logger2.LogInformation($"(this.GetType().Name)被构了222");
        }
​
      [TypeFilter(typeof(CustomResourceAttribute))]
        public IActionResult Index(int id)
        {
            ViewBag.user = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                Id=id,
                Name="a"
​
            });
​
​
            ViewData["class"] = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                Cid = 2,
                 Cname="1班"
​
            }) ;
            return View();
        }
    }
}
​

ActionFilter做日志记录

Log4Net? Nlog? 都是可以的~~

支持Filter构造函数注入--IOC容器来创建

总结:这次主要是讲解AOP的ActionFilter以及IResource的方法,主要是做日志和缓存的,大家可以多了解了解用法。一步步来,加油!