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

.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方法 代码 如下

        public async override Task Invoke(AspectContext context, AspectDelegate next)
        {
            try
            {
                //用方法名称+入参 生成Key
                string key = context.Proxy.ProxyMethod.Name;
                foreach (var item in context.Parameters)
                {
                    key += item.Value;
                }
                //判断缓存是否已经存在
                var isExists = await RedisCache.ExistsAsync(key);
                if (!isExists)
                {
                    //如果不存在缓存 则执行方法 并且缓存方法返回值
                    await next(context);
                    await RedisCache.SetAsync(key, JObject.FromObject(context.ReturnParameter.Value).ToString(), Timeout);
                }
                else
                {              
                    var result = RedisCache.Get(key);
                    if (_type != null)
                    {
                        //判断是否异步返回类型 因为异步方法无法正常转换 需要先取返回后 在异步化
                        dynamic info = JObject.Parse(result).ToObject(_type);
                        context.ReturnParameter.Value = Task.FromResult(info.Result);
                    }
                    else
                        context.ReturnParameter.Value = JObject.Parse(result).ToObject(context.ReturnParameter.ParameterType);
                }
            }
            catch (Exception ex)
            {
                //Aop异常 直接跳过Aop 进入方法
                await next(context);
            }
        }

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

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

    public interface ITestService
    {
        [Cache]
        Test Show();
    }

2.异步方法

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

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

思考

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

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值