.net core 使用 AspectCore 实现简易的AopCache。
程序员文章站
2022-07-11 11:32:05
(第一次写博客,好紧张!!!) 源码地址:传送门 项目中有很多缓存的需求,能自己定义缓存key和时间,能根据key去清理缓存。 网上找了一圈,有很多基于aop的缓存组件,但是都不满足我的需求。故造了个*。 新建web项目 .net core mvc TestAopCache 安装 AopCache ......
(第一次写博客,好紧张!!!)
源码地址:传送门
项目中有很多缓存的需求,能自己定义缓存key和时间,能根据key去清理缓存。
网上找了一圈,有很多基于aop的缓存组件,但是都不满足我的需求。故造了个*。
新建web项目 .net core mvc testaopcache
安装 aopcache
install-package aopcache -version 0.1.1
属性说明
aopcache一共3个属性:
key:缓存的键值,字符串,可以包含占位符 如 {userid}。如果key为空,将用类名+方法名作为键值
type:表示时间类型,枚举。秒、分、小时、天 四种。默认秒
length:时间长度,0 表示永不过去。默认 0
标记方式有两种
1、在接口的方法上加 [aopcache]
2、没有接口,直接在类的方法上加 [aopcache],前提是此方法必须用 virtual修饰
存储方式
默认是 memorycache,不过你可以实现 iaopcacheprovider 接口,实现自己的存储。
新建 itestservice,在方法上加 [aopcache]
public interface itestservice { //默认时间单位是秒,长度为0,即永不过期 [aopcache(key = "aaa")] string getbykey(); //设置3秒过期 这里的“{userid}”,占位符。用参数 userid 的值去替换 [aopcache(key = "bbb_{userid}", length = 3)] string getbykeyandparamter(int userid); //设置十分钟过期 这里的“{req:id}”,占位符。用参数 req里面的id 的值去替换 [aopcache(key = "ccc_{req:id}_{type}", type = cachetimetype.minute, length = 10)] task<userinfo> getuserinfo(int type, req req); }
//实现接口
public class testservice : itestservice { public string getbykey() { return guid.newguid().tostring("n"); } public string getbykeyandparamter(int userid) { return guid.newguid().tostring("n") + "---" + userid; } public async task<userinfo> getuserinfo(int type, req req) { return new userinfo() { id = new random().next(1, 100), name = guid.newguid().tostring("n") }; } }
直接在类的方法上加标签
public class testsingleclass { [aopcache(key = "testsingleclasskey")] public virtual string get() { return guid.newguid().tostring("n"); } }
startup中配置注入
public iserviceprovider configureservices(iservicecollection services) { services.configure<cookiepolicyoptions>(options => { //... //注入打了标签的service services.addtransient<itestservice, testservice>(); services.addtransient<testsingleclass>(); //自定义存储 这里xxx表示 iaopcacheprovider 的实现 //services.addaopcache<xxx>(); //默认内存存储 //返回iserviceprovider,由 aspectcore接管 return services.addaopcacheusedefaultmemoryprovider(); //此方法的内部实现,这里包装一层 //if (setupaction == null) //{ // services.addmemorycache(); //} //else //{ // services.addmemorycache(setupaction); //} //services.addsingleton<iaopcacheprovider, defaultaopcacheprovider>(); //services.configuredynamicproxy(); //return services.buildaspectinjectorprovider(); }
直接在homecontroller 中使用
public class homecontroller : controller { private itestservice testservice { get; set; } private testsingleclass testsingleclass { get; set; } private iaopcacheprovider aopcacheprovider { get; set; } public homecontroller(itestservice testservice, testsingleclass testsingleclass, iaopcacheprovider aopcacheprovider) { testservice = testservice; testsingleclass = testsingleclass; aopcacheprovider = aopcacheprovider; } public iactionresult index() { //在这里清除某个key //清除 getuserinfo aopcacheprovider.remove("ccc_1000_1"); return view(); } public async task<iactionresult> privacy() { //第一次获取值 生成的key是 aaa var v1 = testservice.getbykey(); //生成的key是 bbb_1,占位符被替换:bbb_{userid} => bbb_1 var v2 = testservice.getbykeyandparamter(1); //生成的key是 ccc_1000_1,占位符被替换:ccc_{req:id}_{type} => ccc_1000_1 var v3 = await testservice.getuserinfo(1, new req() { id = 1000 }); //直接在类的方法上加标记,但是方法必须加 virtual //生成的key是 testsingleclasskey var v4 = testsingleclass.get(); //第二次获取值 var v1new = testservice.getbykey(); var v2new = testservice.getbykeyandparamter(1); var v3new = await testservice.getuserinfo(1, new req() { id = 1000 }); var v4new = testsingleclass.get(); var sb = new stringbuilder(); sb.appendline($"getbykey(永不过期):第一次=> {v1}"); sb.appendline($"getbykey(永不过期):第二次=> {v1new}"); sb.appendline($"getbykeyandparamter(3秒):第一次=> {v2}"); sb.appendline($"getbykeyandparamter(3秒):第二次=> {v2new}"); sb.appendline($"getuserinfo(十分钟):第一次=> {newtonsoft.json.jsonconvert.serializeobject(v3)}"); sb.appendline($"getuserinfo(十分钟):第二次=> {newtonsoft.json.jsonconvert.serializeobject(v3new)}"); sb.appendline($"testsingleclass.get(永不过期):第一次=> {v4}"); sb.appendline($"testsingleclass.get(永不过期):第二次=> {v4new}"); return content(sb.tostring()); } [responsecache(duration = 0, location = responsecachelocation.none, nostore = true)] public iactionresult error() { return view(new errorviewmodel { requestid = activity.current?.id ?? httpcontext.traceidentifier }); } }
f5运行
点击 “privacy”,疯狂刷新,查看效果。
切换回首页,清除 getuserinfo 的缓存,再切换到privacy,发现 getuserinfo 的缓存已改变。
到此结束,如果你刚好有这需求,可以参考此文章。源码传到gayhub,求轻拍 ==
上一篇: 雷军晒小米CC9美图定制版自拍:这很OK
推荐阅读
-
使用.Net Core + Vue + IdentityServer4 + Ocelot 实现一个简单的DEMO +源码
-
.Net Core中使用ref和Span
提高程序性能的实现代码 -
.Net Core中使用ref和Span
提高程序性能的实现代码 -
ASP.NET Core 3.0 使用AspectCore-Framework实现AOP
-
使用 .NET Core 3.0 的 AssemblyLoadContext 实现插件热加载
-
ASP.NET Core中使用令牌桶限流的实现
-
如何在ASP.Net Core使用分布式缓存的实现
-
ASP.NET Core使用SkiaSharp实现验证码的示例代码
-
ASP.NET Core 2.1 中的 HttpClientFactory (Part 3) 使用Handler实现传出请求中间件
-
使用.net core中的类DispatchProxy实现AOP