aspnetcore中的过滤器是Aop编程的一种实现形式。记录下学习的过程,方便以后查阅
# ResourceFilter 同步实现
我们新建一个 WebApi 项目,然后创建一个自定义实现的 ResourceFilter (资源过滤器)
public class CustomResourceFilterAttribute : Attribute, IResourceFilter | |
{ | |
// 资源进入之前 | |
public void OnResourceExecuting (ResourceExecutingContext context) | |
{ | |
Console.WriteLine ("请求之前"); | |
} | |
// 资源退出之后 | |
public void OnResourceExecuted (ResourceExecutedContext context) | |
{ | |
Console.WriteLine ("请求之后"); | |
} | |
} |
上面自定义的资源过滤器继承了特性和实现了资源过滤器的接口
# 总结
在框架中凡是系统提供的接口都是给开发者做扩展使用的
实现完自定义的资源过滤器后,将他们标注在相关的 action 上面
[Route ("/api/[action]")] | |
public class ResourceController : ControllerBase | |
{ | |
private readonly ILogger<ResourceController> _logger; | |
public ResourceController (ILogger<ResourceController> logger) | |
{ | |
_logger = logger; | |
Console.WriteLine ("构造函数"); | |
} | |
[HttpGet] | |
[CustomResourceFilter] | |
public string ResourceIndex () | |
{ | |
Console.WriteLine ("方法执行中"); | |
return "success"; | |
} | |
} |
# 运行项目
# 结论
OnResourceExecuting-》控制器构造函数-》调用的API(action)-》OnResourceExecuted
# ResourceFilter 异步实现
同步和异步原理和步骤上是一样的,书写的代码有所不同.
public class CustomAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter | |
{ | |
public async Task OnResourceExecutionAsync (ResourceExecutingContext context, ResourceExecutionDelegate next) | |
{ | |
Console.WriteLine ("执行之前 Async"); | |
ResourceExecutedContext resource = await next.Invoke (); | |
Console.WriteLine ("执行之后 Async"); | |
} | |
} |
[Route ("/api/[action]")] | |
public class ResourceController : ControllerBase | |
{ | |
private readonly ILogger<ResourceController> _logger | |
public ResourceController (ILogger<ResourceController> logger) | |
{ | |
_logger = logger; | |
Console.WriteLine ("构造函数"); | |
[HttpGet] | |
[CustomAsyncResourceFilterAttribute] | |
public string ResourceAsyncIndex () | |
{ | |
Console.WriteLine ("方法执行中"); | |
return "success"; | |
} | |
} |
# ResourceFilter 在业务上能用来做什么
缓存
下面实现缓存的代码以异步实现
public class CustomAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter | |
{ | |
public async Task OnResourceExecutionAsync (ResourceExecutingContext context, ResourceExecutionDelegate next) | |
{ | |
Console.WriteLine ("执行之前 Async"); | |
string requestPath = context.HttpContext.Request.Path; | |
bool sign = await RedisHelper.Do (d => d.KeyExistsAsync (requestPath)); | |
if (sign) | |
{ | |
string value = await RedisHelper.StringGetAsync (requestPath); | |
// 类似于短路。context.Result 赋值后就会终止 | |
context.Result = new JsonResult (value); | |
} | |
else | |
{ | |
// 获取 action 中的结果 | |
ResourceExecutedContext resource = await next.Invoke (); | |
dynamic Result = resource.Result; | |
// 缓存 20 秒 | |
await RedisHelper.StringSetAsync (requestPath, Result.Value, TimeSpan.FromSeconds (20)); | |
string value = await RedisHelper.StringGetAsync (requestPath); | |
Console.WriteLine (value); | |
} | |
Console.WriteLine ("执行之后 Async"); | |
} | |
} |
上面 RedisHelper 的操作类库是自己封装了一下,方便调用。redis 的 nuget 地址如果服务器还没有过期