AOP学习-基于Emit和Attribute的简单AOP实现
关于AOP的介绍,园子里曾经有段时间非常热。
我也看了很多AOP相关的文章,对AOP的概念有一定的了解,觉得园子里的大牛张逸的AOP介绍很不错:AOP技术基础
看了很多AOP的介绍之后,很想自己实现一个简单的AOP来感受一下,但是一直苦于不知道怎么实现。
后来看了园子里的一个介绍Emit的系列(Emit学习系列文章导航),才开始在原作者的基础上实现了简单的AOP框架,仅供学习使用。
1. ThinAOP的介绍
此框架非常简单,只有几个文件。但是就是因为简单,所以可以用来学习AOP的思想。
由于主要部分是有Emit实现的,所以没有Emit基础的话,最好先看一下Emit学习系列文章导航
具体结构如下:
2. ThinAOP的介绍-ProxyFactory
之所以先介绍ProxyFactory,是因为ProxyFactory是ThinAOP对外的接口,对于需要使用AOP的类,需要使用ProxyFactory来生成相应的代理类。
ProxyFactory类中只有一个静态方法,就是用来生成动态代理类的。
1 2 3 4 5 6 7 8 9 10 | public class ProxyFactory { public static T CreateProxy<T>(Type realProxyType) { var generator = new DynamicProxyGenerator(realProxyType, typeof (T)); Type type = generator.GenerateType(); return (T)Activator.CreateInstance(type); } } |
3. ThinAOP的介绍-Metadata
Metadata中定义了四个类:
- ExceptionMetadata:用于保存程序中exception的信息
- MethodMetadata :用于保存程序中方法的信息(目前只有方法名)
- ParameterMetadata:用于保存程序中方法的参数信息
- ResultMetadata:用于保存程序中方法的返回值信息
通过上面定义的四个类,我们可以看出此AOP框架值主要是针对方法这个级别的拦截。即拦截方法在执行前,执行后,异常时的操作。
这四个类非常简单,只是定义了一些属性。
4. ThinAOP的介绍-InvokeContext
保存了必须的上下文信息,也就是上面定义的那些Metadata
5. ThinAOP的介绍-DynamicProxyGenerator
这个类是整个框架的核心,用来生成动态代理,在代理中完成对方法的拦截操作,并在拦截后注入自己的代码。
核心方法是GenerateType,根据现有type生成新的type
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public Type GenerateType() { // 构造程序集 BuildAssembly(); // 构造模块 BuildModule(); // 构造类型 BuildType(); // 构造字段 BuildField(); // 构造函数 BuildConstructor(); // 构造方法 BuildMethods(); Type type = _typeBuilder.CreateType(); // 将新建的类型保存在硬盘上(如果每次都动态生成,此步骤可省略) _assemblyBuilder.Save(AssemblyFileName); return type; } |
其中的Emit代码,我已经写了相应的C#代码。
Emit代码类似IL,我也是先写C#代码,然后用ILSpy转成IL代码,然后参照IL代码来写的Emit部分代码。
6. ThinAOP的介绍-AspectAttribute
这个类定义了一系列的Attribute,方便于定义拦截操作。
主要定义了3中拦截操作:分别是执行前拦截 ,执行后拦截,异常时拦截
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [AttributeUsage(AttributeTargets.Method)] public abstract class PreAspectAttribute : AspectAttribute { } [AttributeUsage(AttributeTargets.Method)] public abstract class PostAspectAttribute : AspectAttribute { } [AttributeUsage(AttributeTargets.Method)] public abstract class ExceptionAspectAttribute : AspectAttribute { } |
PS.
整个框架的实现参考了博客园里很多文章,这里就不一一列举了。
除了ThinAOP的框架外,我还写了了一个使用这个框架的例子,具体请参见提供的附件:ThinAOP
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人