一起养成写作习惯!这是我参与「掘金日新计划 · 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的方法,主要是做日志和缓存的,大家可以多了解了解用法。一步步来,加油!