.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则分别为我们构建了一个物理文件系统和程序集内嵌文 ...
随机推荐
- swift textfiled 输入完毕 return 隐藏键盘 方法
学习swift 真是件头疼的事情 会的人少,又没有OC基础,所以 且学切珍惜吧. 在做登录的时候发现textfiled 自动调用键盘后不能隐藏?头疼 ~~~~询问了好多人 终于有人自写解答 为了方便后 ...
- vc项目中加载多个lib遇到的问题
一个VC项目中 在网络加密 json解析等方面 加载了多个第三方库和文件 boost cryptpp rapidjson mysql的连接池等等 在使用mysql++的时候 多次报错 LNK 20 ...
- Shortest Unsorted Continuous Subarray LT581
Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...
- windows 下设置nginx负载均衡
#user nobody; worker_processes ; #error_log logs/error.log; #error_log logs/error.log notice; #error ...
- fastcgi协议解析(nginx)
请求NGINX ->[ {(post data) +> (NGX_HTTP_FASTCGI_STDIN)} * N +> {(environment variables) +> ...
- Mockito学习1
Mockito学习1 junitmaven软件测试框架项目管理 Mockito是一个流行的Mocking框架.它使用起来简单,学习成本很低,而且具有非常简洁的API,测试代码的可读性很高.因此它十分 ...
- 【搜索】C - Catch That Cow
#include<stdio.h> #include<string.h> struct A{ int state; int step; }queue[]; // 结构体数组用来 ...
- spring学习 十 schema-based 前置后后置通知
spring 提供了 2 种 AOP 实现方式:(1)Schema-based ,(2)AspectJ Schema-based:每个通知都需要实现接口或类,配置 spring 配置文件时在<a ...
- List<T>中,Remove和RemoveAt区别
Remove删除的是匹配的第一项.比如你的list里面有2个相同的项.那么就删除第一个.后面的不删除,找不到元素和删除失败都返回falseRemoveAt是删除索引下的项
- unity在一个对象上挂多个一样的脚本怎么获取
使用GetComponents获取,存到一个该类的数组里