.Net core+Reds如何实现Aop缓存

一世执手 提交于 2020-04-26 13:56:41

.Net core+Reds如何实现Aop缓存

前言
在实际开发的场景中,有很多需要缓存的数据,为了减少重复代码的编写,想采用Aop的方式来实现切面编程减少对以有业务代码的改动和侵入性。
在传统的 .Net Framework项目中实现Aop有很多简单的方式,但是在 .Net Core中尤其是1.X版本笔者没有找到比较好的解决方案采用了一个三方开源的Aop库,下面会写出来。

准备
本次采用的环境是 .Net Core 1.1版本
本次使用的Aop 开源库是 AspectCore 0.1.2版本

实践
Aop顾名思义面向切面编程,是一种通过预编译和运行时动态代理来实现的一种技术,本文中采用了三方开源的Aop库 AspectCore 是.Net Core 中一个轻量级和模块化的Aop 解决方案
首先创建一个 缓存特性 CacheAttribute 继承 AspectCore中的 InterceptorAttribute并且重写 InterceptorAttribute中的 Invoke方法 代码 如下

 1         public async override Task Invoke(AspectContext context, AspectDelegate next)
 2         {
 3             try
 4             {
 5                 //用方法名称+入参 生成Key
 6                 string key = context.Proxy.ProxyMethod.Name;
 7                 foreach (var item in context.Parameters)
 8                 {
 9                     key += item.Value;
10                 }
11                 //判断缓存是否已经存在
12                 var isExists = await RedisCache.ExistsAsync(key);
13                 if (!isExists)
14                 {
15                     //如果不存在缓存 则执行方法 并且缓存方法返回值
16                     await next(context);
17                     await RedisCache.SetAsync(key, JObject.FromObject(context.ReturnParameter.Value).ToString(), Timeout);
18                 }
19                 else
20                 {              
21                     var result = RedisCache.Get(key);
22                     if (_type != null)
23                     {
24                         //判断是否异步返回类型 因为异步方法无法正常转换 需要先取返回后 在异步化
25                         dynamic info = JObject.Parse(result).ToObject(_type);
26                         context.ReturnParameter.Value = Task.FromResult(info.Result);
27                     }
28                     else
29                         context.ReturnParameter.Value = JObject.Parse(result).ToObject(context.ReturnParameter.ParameterType);
30                 }
31             }
32             catch (Exception ex)
33             {
34                 //Aop异常 直接跳过Aop 进入方法
35                 await next(context);
36             }
37         }

 



上面的代码展示了 如何使用AspectCore结合Redis实现Aop缓存,在实现的过程中笔者发现,异步方法没有办法通过Json正常的转换,所以先通过取值在进行异步化,如果有哪位大神有好的解决方案还请告知一二(十分感谢),同步方法没有问题可以正常Json和转换。

实现了核心的Aop的代码最后使用的时候 很简单代码如下几种情况
1.同步方法
 

1    public interface ITestService
2     {
3         [Cache]
4         Test Show();
5     }

 


2.异步方法

1     public interface ITestService
2     {
3         [Cache(typeof(Parameter<Test>))]
4         Task<Test> Show(string input);
5     }

 


只要在接口的方法上标上Cache 特性即可实现对现有业务无入侵的改造

思考
在这次实现Aop 的过程中,笔者一直有个疑问在Aop缓存的实现中,通过缓存整个方法的返回是不是一个好的解决方案,在一些特殊的业务场景中如果这个方法返回是一个复杂的类型 是否会有异常?如果不通过缓存整个方法返回 是否还有什么更好的解决方案? 如果各位大神有更好的解决方案,还请多多指教,现在这里感谢了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!