一 基础概念。
当一个通用的新需求产生时(异常处理,加日志)
普通方法 。
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();
}
}
}
执行效果 。
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>
来个异步的实现例子。
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;
}
}
}
}
使用方法一样。在控制器内添加属性。
使用场景
天生适合做缓存。