在一些项目中往往会使用Redis用作缓存查询,授权等,这里简单记录一下在.NET WebApi项目中使用过滤器+MemoryCache实现缓存查询
1、Startup中注册缓存服务
services.AddMemoryCache();
2、创建一个自定义过滤器(这里使用资源过滤器)
public class CustomResourceFilteAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
}
}
注意这里继承了Attribute,因为到时候可以把它当作注解直接在控制器中使用,继承IResourceFilter然后实现它的两个方法,这里以资源过滤器为例
3、通过构造注入缓存
private readonly IMemoryCache _Cache;
public CustomResourceFilteAttribute(IMemoryCache cache)
{
_Cache = cache;
}
4、实现IResourceFilter接口方法
public void OnResourceExecuted(ResourceExecutedContext context)
{
var path = context.HttpContext.Request.Path;
var route = context.HttpContext.Request.QueryString.Value;
var key = path + route;
_Cache.Set(key, context.Result);
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
var path=context.HttpContext.Request.Path; //api/BlogPost
var route = context.HttpContext.Request.QueryString.Value; //?page=1&size=2
var key = path + route;
if (_Cache.TryGetValue(key, out object value)){
context.Result = value as IActionResult;
}
}
通过上下文获取到请求路劲和路由,拼接起来作为缓存的Key
在OnResourceExecuting方法中通过TryGetValue尝试获取我们拼接好的Key,如果存在,就直接把value转换后给到上下文的Result返回
5、使用特性
[TypeFilter(typeof(CustomResourceFilteAttribute))]
[HttpGet]
public async Task<ActionResult<ApiResult>> Get([FromServices]IMapper iMapper, int page,int size)
6、调试看执行步骤
分别在控制器接口方法、OnResourceExecuted方法、OnResourceExecuting方法打上断点
可以发现当第一次执行时步骤是:OnResourceExecuting==》controller接口 ==》OnResourceExecuted ==》结束
第二次执行步骤是:OnResourceExecuting==》结束
第一次进入OnResourceExecuting发现缓存中没有该Key 就跑到控制器层走原有的接口方法进行查询,走完进入OnResourceExecuted把这个Key和接口保存到缓存
第二次执行时进入OnResourceExecuting 发现缓存中有这个缓存就把值赋值给Result就直接返回了