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

源码地址:传送门

项目中有很多缓存的需求,能自己定义缓存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. npm run build出问题十分通用的解决方法

    1.C:\NanoFabric\52ABP\SPAHost\ClientApp\node_modules 原来的目录重命名为C:\NanoFabric\52ABP\SPAHost\ClientApp\ ...

  2. day16正则表达式作业

    1.匹配一篇英文文章的标题 类似 The Voice Of China #([A-Z][a-z]*)( [A-Z][a-z]*)* 2.匹配一个网址 #(https|http|ftp):\/\/[^\ ...

  3. mysql下载、安装

    一.下载 网上下载地址五花八门,为了防止出现不必要的麻烦,建议直接从官网下载.有几点好处: 1.没有任何其他捆绑的软件 2.版本分布清晰,一般建议选择较新版本    mysql官网下载地址:https ...

  4. springboot 配置DRUID数据源

    druid 是阿里开源的数据库连接池. 开发时整合   druid 数据源过程. 1.修改pom.xml <dependency> <groupId>mysql</gro ...

  5. 第07章:MongoDB-CRUD操作--文档--创建

    ①语法 insert() save()  --有修改没有新增 insertOne() [3.2版本新增]向指定集合中插入一条文档数据 insertMany() [3.2版本新增]向指定集合中插入多条文 ...

  6. python 基础_列表的其他操作 4

    一.查找某个元素在数组中出现的次数 ,count的运用 a = ['a','b','c','c','c','a'] print(a.count('c')) 二.把一个元素插入到另一个元素的末尾,ext ...

  7. Linux后台开发工具箱

    https://files-cdn.cnblogs.com/files/aquester/Linux后台开发工具箱.pdf 目录 目录 1 1. 前言 3 2. 脚本类工具 3 2.1. sed命令- ...

  8. Qt_MainWindow简介

    QMainWindow 是Qt框架带来的一个预定义好的主窗口类.按照建立HelloWorld程序建立工程,直接运行,或有一个空窗口. main().cpp #include "mainwin ...

  9. (最大上升子序列)Monkey and Banana -- hdu -- 1069

    http://acm.hdu.edu.cn/showproblem.php?pid=1069      Monkey and Banana Time Limit:1000MS     Memory L ...

  10. java实现把两张图片合并(Graphics2D)

    package com.yin.text; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.i ...