0. 前言

之前写了几篇文章介绍了一些AOP的知识,

但是还没有亮出来AOP的姿势,

也许姿势漂亮一点,

大家会对AOP有点兴趣

内容大致会分为如下几篇:(毕竟人懒,一下子写完太累了,没有动力)

  1. AOP的姿势之 简化 MemoryCache 使用方式
  2. AOP的姿势之 简化混用 MemoryCache 和 DistributedCache 使用方式
  3. AOP的姿势之 如何把 HttpClient 变为声明式

至于AOP框架在这儿示例依然会使用我自己基于emit实现的动态代理AOP框架: https://github.com/fs7744/Norns.Urd

毕竟是自己写的,魔改/加功能都很方便,

万一万一大家如果有疑问,(虽然大概不会有),我也好回答, (当然如果大家认可,在github给个star,就实在是太让人开心了)

1. 正文

1.1 回顾 MemoryCache如何使用

var cache = ServiceProvider.GetRequiredService<IMemoryCache>();
var r = await cache.GetOrCreateAsync(cacheKey, async e =>
{
var rr = await do();
e.AbsoluteExpirationRelativeToNow = absoluteExpirationRelativeToNow;
return rr;
});

MemoryCache 本身已经被封装到如此简单就可以使用了

但是呢,每次我们使用的时候依然要这样重复写类似的代码

当然我们都是拥有超强的 ctrl+c 和 ctrl+v 能力,

这点点重复代码都是些毛毛雨啦,

上w行代码一把梭都是小场面了,

不过呢,这样的代码写的和在校的学生一样,

怎么能体现我们混迹江湖,加班数十载的逼格呢?

我们要让这些在校学生/实习生看不懂我们的代码,

让他们看不到GetOrCreateAsync

让他们调试的时候 do() 里面的断点跑不到

这样我们才能展示出扫地僧的实力:来,小朋友,我来教你新姿势

1.2 逼格启航

1.2.1 逼格核心 - 拦截器

在Norns.Urd中,Interceptor 拦截器是用户可以在方法插入自己的逻辑的核心。

标准结构为IInterceptor

public interface IInterceptor
{
// 用户可以通过Order自定义拦截器顺序,排序方式为ASC,全局拦截器和显示拦截器都会列入排序中
int Order { get; } // 同步拦截方法
void Invoke(AspectContext context, AspectDelegate next); // 异步拦截方法
Task InvokeAsync(AspectContext context, AsyncAspectDelegate next); // 可以设置拦截器如何选择过滤是否拦截方法,除了这里还有NonAspectAttribute 和全局的NonPredicates可以影响过滤
bool CanAspect(MethodInfo method);
}

这里我们为了大家理解简单,就使用最简单的方式来做 : 使用 AbstractInterceptorAttribute

一个非常简单的例子就如下了:

    public class CacheAttribute : AbstractInterceptorAttribute
{
private readonly TimeSpan absoluteExpirationRelativeToNow;
private readonly string cacheKey; // 为了简单,缓存策略我们就先只支持TTL 存活固定时间
public CacheAttribute(string cacheKey, string absoluteExpirationRelativeToNow)
{
this.cacheKey = cacheKey;
this.absoluteExpirationRelativeToNow = TimeSpan.Parse(absoluteExpirationRelativeToNow);
} public override async Task InvokeAsync(AspectContext context, AsyncAspectDelegate next)
{
// 整个代码基本和我们直接使用 MemoryCache 一样
var cache = context.ServiceProvider.GetRequiredService<IMemoryCache>();
var r = await cache.GetOrCreateAsync(cacheKey, async e =>
{
await next(context); // 所以真正实现的方法逻辑都在 next 中,所以调用它就好了
e.AbsoluteExpirationRelativeToNow = absoluteExpirationRelativeToNow;
return context.ReturnValue; // 结果都在ReturnValue , 这里为了简单,就不写 void / Task<T> / ValueTask<T> 等等 各种返回值的兼容代码了
});
context.ReturnValue = r; // 设置 ReturnValue, 由于缓存有效期内, next不会被调用, 所以ReturnValue不会有值,我们需要将缓存结果设置到 ReturnValue
}
}

1.2.2 测试一下

 public interface ITestCacheClient
{
string Say(string v);
} public class TestCacheClient : ITestCacheClient
{
public string Say(string v) => v;
} static class Program
{
static void Main(string[] args)
{
var client = new ServiceCollection()
.AddMemoryCache()
.AddSingleton<ITestCacheClient, TestCacheClient>()
.ConfigureAop()
.BuildServiceProvider()
.GetRequiredService<ITestCacheClient>();
Console.WriteLine(client.Say("Hello World!"));
Console.WriteLine(client.Say("Hello Two!"));
Thread.Sleep(3000);
Console.WriteLine(client.Say("Hello Two!"));
}
}

Console 结果

Hello World!
Hello Two!
Hello Two!

加上缓存设置:

    public class TestCacheClient : ITestCacheClient
{
[Cache(nameof(Say), "00:00:03")]
public string Say(string v) => v;
}

再次测试的 Console 结果

Hello World!
Hello World!
Hello Two!

例子代码都在 https://github.com/fs7744/AopDemoList/tree/master/MakeMemoryChacheSimple

处理情况更全面的例子在 https://github.com/fs7744/Norns.Urd/tree/main/src

祝大家都能愉快被叫 大神 nb。

AOP的姿势之 简化 MemoryCache 使用方式的更多相关文章

  1. AOP的姿势之 简化混用 MemoryCache 和 DistributedCache 的方式

    0. 前言 之前写了几篇文章介绍了一些AOP的知识, 但是还没有亮出来AOP的姿势, 也许姿势漂亮一点, 大家会对AOP有点兴趣 内容大致会分为如下几篇:(毕竟人懒,一下子写完太累了,没有动力) AO ...

  2. 6.AOP配置与应用(xml的方式)

    xml 配置 AOP 1.将 拦截其器对象 初始化到容器中 2.<aop:config> <aop:aspect.... <aop:pointcut <aop:befor ...

  3. AOP的具体实践-简化结果返回的处理

    原因: 以前学习Spring的时候着重学习过AOP概念,但是一直也没有用上,唯一碰到过的就是Spring内置的事务管理.现在碰到过一些结果后面的操作适合用到,所以这里就拿出来用一下,并且复习一下落下的 ...

  4. SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP

    AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...

  5. Dora.Interception,为.NET Core度身打造的AOP框架 [2]:以约定的方式定义拦截器

    上一篇<更加简练的编程体验>提供了最新版本的Dora.Interception代码的AOP编程体验,接下来我们会这AOP框架的编程模式进行详细介绍,本篇文章着重关注的是拦截器的定义.采用“ ...

  6. Java 中 AOP —— 探讨其存在价值及实现方式对比

    AOP 概述 Aspect-oriented programming(面向切面编程).最广为人知的面向侧面的程序设计语言是由施乐帕洛阿尔托研究中心 (施乐帕克 nb!)开发的AspectJ,该语言可以 ...

  7. 【学习】Spring 的 AOP :基于Annotation 的“零配置”方式

    转自:http://www.cnblogs.com/jbelial/archive/2012/07/20/2539123.html AOP(Aspect Orient Programming ) , ...

  8. Spring 详解(二)------- AOP关键概念以及两种实现方式

    目录 1. AOP 关键词 2. AOP 的作用 3. AOP 的通知类型 4. 基于 xml 的配置方式 5. 基于注解的配置方式 6. 切面的优先级 7. 重用切点表达式 8. 两种方式的比较(摘 ...

  9. Spring的AOP开发(基于AspectJ的XML方式)

    Spring的AOP的简介: AOP思想最早是由AOP联盟组织提出的.Spring是使用这种思想最好的框架 Spring的AOP有自己实现的方式(非常繁琐). Aspect是一个AOP的框架, Spr ...

随机推荐

  1. Qt5字符串编码转换学习

    目录 1.通过Python3示例探索常用字符串编码 UTF8 ANSI Unicode 小结 2.Qt5中使用QTextCodec进行编码转换 小结 1.通过Python3示例探索常用字符串编码 下面 ...

  2. 推荐:国产etl调度工具Taskctl web应用版,0元永久授权

    写在前面 2020年疫情席卷全球,更是对整个市场经济造成了严重影响,年初疫情肆虐,西方世界单方面的科技.经济封锁,国际关系吃紧.....导致很多中小型企业业务链受阻,大型企业经费资金吃紧,轮班制导致公 ...

  3. SQL优化之SQL 进阶技巧(上)

    由于工作需要,最近做了很多 BI 取数的工作,需要用到一些比较高级的 SQL 技巧,总结了一下工作中用到的一些比较骚的进阶技巧,特此记录一下,以方便自己查阅,主要目录如下: SQL 的书写规范 SQL ...

  4. 推荐系统实践 0x0c FM系列

    逻辑回归(LR) 在介绍FM系列之前,我想首先简单介绍一下逻辑回归.通常来说,逻辑回归模型能够综合利用更多的信息,如用户.物品.上下文等多种不同的特征,生成更为全面的结果.另外,逻辑回归将推荐问题看成 ...

  5. XSS漏洞防御之HttpOnly

    WWW服务依赖于Http协议实现,Http是无状态的协议,所以为了在各个会话之间传递信息,就需要使用Cookie来标记访问者的状态,以便服务器端识别用户信息. Cookie分为内存Cookie和硬盘C ...

  6. 百度前端技术学院-基础-day22-24

    第二十二天到第二十四天:JavaScript里面的居民们 task1 题目: <div> <label>Number A:<input id="radio-a& ...

  7. CSS全览_选择符+特指+单位+字体

    CSS全览_选择符+特指+单位+字体 目录 CSS全览_选择符+特指+单位+字体 1. CSS样式 2. 选择符 3. 特指度和层叠 4. 值和单位 5. 字体 作者: https://www.cnb ...

  8. 深入理解Java虚拟机(五)——JDK故障处理工具

    进程状况工具:jps jps(JVM Process Status Tool) 作用 用于虚拟机中正在运行的所有进程. 显示虚拟机执行的主类名称以及这些进程的本地虚拟机唯一ID. 可以通过RMI协议查 ...

  9. sublime text3 将tab转换为2个或4个空格,并显示空格

    有很多软件并不能解析tab,而往往有的程序员喜欢使用tab键进行对齐,sublime text可以很好的解决这个问题. 首先打开sublime text,点击preferences->setti ...

  10. HDFS 操作命令

    本地文件系统创建一个文件,输入带姓名学号信息. 查看新建文件所在目录 查看新建文件内容 将此文件上传到HDFS文件系统上的用户目录 HDFS上查看相应目录 HDFS上查看文件内容 HDFS上查看文件大 ...