(第一次写博客,好紧张!!!)

源码地址:传送门

项目中有很多缓存的需求,能自己定义缓存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。的更多相关文章

  1. [Asp.Net Core轻量级Aop解决方案]AspectCore Project 介绍

    AspectCore Project 介绍 什么是AspectCore Project ? AspectCore Project 是适用于Asp.Net Core 平台的轻量级 Aop(Aspect- ...

  2. ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系

    ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...

  3. .NetCore中使用AspectCore、ExceptionLess 实现AOP操作日志记录

    结合前面封装的ExceptionLess,接下来使用 AspectCore 实现AOP日志处理 nuget导入AspectCore.Core .AspectCore.Extensions.Depend ...

  4. .netcore 中使用开源的AOP框架 AspectCore

    AspectCore Project 介绍 什么是AspectCore Project ? AspectCore Project 是适用于Asp.Net Core 平台的轻量级 Aop(Aspect- ...

  5. 基于asp.net core 从零搭建自己的业务框架(一)

    前言 asp.net core版本选择2.2,只是因为个人习惯了vs2017,代码以及设计皆可移植到vs2019,用asp.net core 3.0以及以上运行起来 项目类似选择web api,基础设 ...

  6. ASP.NET Core路由中间件[1]: 终结点与URL的映射

    目录 一.路由注册 二.设置内联约束 三.默认路由参数 四.特殊的路由参数 借助路由系统提供的请求URL模式与对应终结点(Endpoint)之间的映射关系,我们可以将具有相同URL模式的请求分发给应用 ...

  7. 注册URL模式与HttpHandler的映射关系

    注册URL模式与HttpHandler的映射关系 ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHan ...

  8. 利用.NET Core类库System.Reflection.DispatchProxy实现简易Aop

    背景 Aop即是面向切面编程,众多Aop框架里Castle是最为人所知的,另外还有死去的Spring.NET,当然,.NET Core社区新秀AspectCore在性能与功能上都非常优秀,已经逐渐被社 ...

  9. .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”

    FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...

随机推荐

  1. 关键词提取_textbank

    脱离语料库,仅对单篇文档提取 (1) pageRank算法:有向无权,平均分配贡献度 基本思路: 链接数量:一个网页越被其他的网页链接,说明这个网页越重要 链接质量:一个网页被一个越高权值的网页链接, ...

  2. 1.preparation

    1)Evarobot 安装 http://wiki.ros.org/Robots/evarobot/Tutorials/indigo/Evarobot%20Installation 2)PC 安装 a ...

  3. O365 Manager Plus详解

  4. Python之入门篇1

    一.安装python解释器 官网: https://www.python.org/downloads/windows/ 自行下载安装,添加环境变量 #测试安装是否成功 windows --> 运 ...

  5. 674. Longest Continuous Increasing Subsequence

    static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...

  6. 对SVC和SVR的理解

    首先: support vector classify(SVC)支持分类机做二分类的,找出分类面,解决分类问题 support vector regression(SCR)支持回归机做曲线拟合.函数回 ...

  7. C#中string类型是值类型还是引用类型?(转)

    出处:https://www.cnblogs.com/dxxzst/p/8488567.html .Net框架程序设计(修订版)中有这样一段描述:String类型直接继承自Object,这使得它成为一 ...

  8. Le Chapitre I

    Lorsque j'avais six ans j'ai vu, une fois, une magnifique image, dans un livre sur la Forêt[fɔrε] Vi ...

  9. JAVA技术路线2

    https://www.zhihu.com/question/56110328 1.JavaSE学习视频 http://pan.baidu.com/s/1bp3g6rd2.javaweb的学习视频 h ...

  10. ROM的一种写法

    module mr_rom_pll_valuemask_8bpc #( , , , , // 6*7 // alt_clogb2(42) ) ( input wire clock, :] addr_p ...