.net core 使用 AspectCore 实现简易的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 = )]
string GetByKeyAndParamter(int userId); //设置十分钟过期 这里的“{req:Id}”,占位符。用参数 req里面的Id 的值去替换
[AopCache(Key = "ccc_{req:Id}_{type}", Type = CacheTimeType.Minute, Length = )]
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(, ),
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(); //生成的key是 ccc_1000_1,占位符被替换:ccc_{req:Id}_{type} => ccc_1000_1
var v3 = await TestService.GetUserInfo(, new Req() { Id = }); //直接在类的方法上加标记,但是方法必须加 virtual
//生成的key是 TestSingleClassKey
var v4 = TestSingleClass.Get(); //第二次获取值
var v1New = TestService.GetByKey(); var v2New = TestService.GetByKeyAndParamter(); var v3New = await TestService.GetUserInfo(, new Req() { Id = }); 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 = , Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
F5运行

点击 “Privacy”,疯狂刷新,查看效果。

切换回首页,清除 GetUserInfo 的缓存,再切换到Privacy,发现 GetUserInfo 的缓存已改变。

到此结束,如果你刚好有这需求,可以参考此文章。源码传到gayhub,求轻拍 ==
.net core 使用 AspectCore 实现简易的AopCache。的更多相关文章
- [Asp.Net Core轻量级Aop解决方案]AspectCore Project 介绍
AspectCore Project 介绍 什么是AspectCore Project ? AspectCore Project 是适用于Asp.Net Core 平台的轻量级 Aop(Aspect- ...
- ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系
ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...
- .NetCore中使用AspectCore、ExceptionLess 实现AOP操作日志记录
结合前面封装的ExceptionLess,接下来使用 AspectCore 实现AOP日志处理 nuget导入AspectCore.Core .AspectCore.Extensions.Depend ...
- .netcore 中使用开源的AOP框架 AspectCore
AspectCore Project 介绍 什么是AspectCore Project ? AspectCore Project 是适用于Asp.Net Core 平台的轻量级 Aop(Aspect- ...
- 基于asp.net core 从零搭建自己的业务框架(一)
前言 asp.net core版本选择2.2,只是因为个人习惯了vs2017,代码以及设计皆可移植到vs2019,用asp.net core 3.0以及以上运行起来 项目类似选择web api,基础设 ...
- ASP.NET Core路由中间件[1]: 终结点与URL的映射
目录 一.路由注册 二.设置内联约束 三.默认路由参数 四.特殊的路由参数 借助路由系统提供的请求URL模式与对应终结点(Endpoint)之间的映射关系,我们可以将具有相同URL模式的请求分发给应用 ...
- 注册URL模式与HttpHandler的映射关系
注册URL模式与HttpHandler的映射关系 ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHan ...
- 利用.NET Core类库System.Reflection.DispatchProxy实现简易Aop
背景 Aop即是面向切面编程,众多Aop框架里Castle是最为人所知的,另外还有死去的Spring.NET,当然,.NET Core社区新秀AspectCore在性能与功能上都非常优秀,已经逐渐被社 ...
- .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”
FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...
随机推荐
- Python之路(第五篇) Python基本数据类型集合、格式化、函数
一.变量总结 1.1 变量定义 记录某种状态或者数值,并用某个名称代表这个数值或状态. 1.2 变量在内存中的表现形式 Python 中一切皆为对象,数字是对象,列表是对象,函数也是对象,任何东西都是 ...
- 专访UI中国认证设计师卤大湿 | 一位UI大师关于UI设计的思考
现如今,设计师可以说是一个自带光环的Title,很多深藏不漏的UI设计师们都在以自己的方式为产品设计做出贡献,卤大湿便是这其中之一. 精分青年卤大湿,这个在UI中国上是张酷酷的鲁迅头像的UI设计师,是 ...
- centOS 6.5下升级mysql,从5.1升级到5.6
转载:https://www.cnblogs.com/vickygu2007/p/5066409.html #mysqldump -uroot -p --all-databases > data ...
- ATM自动取款机程序感想
上周四的Java考试,老师并没有我们考暑假给我们布置的样卷的java程序,而是让我们做一个设计ATM的程序,然而这个对于我们来说好难,因为暑假没有学好java,首先基础知识还没有掌握,输入数据一开始都 ...
- JS页面跳转大全
所谓的js页面跳转就是利用javesrcipt对打开的页面ULR进行跳转,如我们打开的是A页面,通过javsrcipt脚本就会跳转到B页面.目前很多垃圾站经常用js跳转将正常页面跳转到广告页面,当然也 ...
- hdu-1033(格式)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1033 参考文章:https://blog.csdn.net/curson_/article/detai ...
- IntelliJ IDEA 2017版 spring-boot 2.0.3 邮件发送搭建,概念梳理 (二)
第二部分 邮件发送历史 一.第一封邮件 1.1969年10月,世界上的第一封电子邮件 1969年10月世界上的第一封电子邮件是由计算机科学家Leonard K.教授发给他的同事的一条简短 ...
- 使用函数的列 group by 分组需要别名
问题描述 使用如下截图的SQL统计数据,报1105错误,提示all columns in group by clause should be in the selected column. 给格式化 ...
- 主机网络ping: unknown host baidu.com问题解决
本机环境: 系统:Centos 网络:NAT 虚拟机之前一直都可以连外网,但最近不能连了,现状如下: [root@vhost03 ~]# ping baidu.comping: unknown hos ...
- 用IrisSkin2.dll美化你的WinForm
From:http://hi.baidu.com/tr0j4n 在WinForm中,可以方便地给自己的程序添加皮肤,做出各种绚丽的效果,而只需要很简单的几句代码即可搞定,下面来领略下. 前期准备:1. ...