AOP學(xué)習(xí)-基于Emit和Attribute的簡(jiǎn)單AOP實(shí)現(xiàn)
關(guān)于AOP的介紹,園子里曾經(jīng)有段時(shí)間非常熱。
我也看了很多AOP相關(guān)的文章,對(duì)AOP的概念有一定的了解,覺得園子里的大牛張逸的AOP介紹很不錯(cuò):AOP技術(shù)基礎(chǔ)
看了很多AOP的介紹之后,很想自己實(shí)現(xiàn)一個(gè)簡(jiǎn)單的AOP來感受一下,但是一直苦于不知道怎么實(shí)現(xiàn)。
后來看了園子里的一個(gè)介紹Emit的系列(Emit學(xué)習(xí)系列文章導(dǎo)航),才開始在原作者的基礎(chǔ)上實(shí)現(xiàn)了簡(jiǎn)單的AOP框架,僅供學(xué)習(xí)使用。
1. ThinAOP的介紹
此框架非常簡(jiǎn)單,只有幾個(gè)文件。但是就是因?yàn)楹?jiǎn)單,所以可以用來學(xué)習(xí)AOP的思想。
由于主要部分是有Emit實(shí)現(xiàn)的,所以沒有Emit基礎(chǔ)的話,最好先看一下Emit學(xué)習(xí)系列文章導(dǎo)航
具體結(jié)構(gòu)如下:
2. ThinAOP的介紹-ProxyFactory
之所以先介紹ProxyFactory,是因?yàn)镻roxyFactory是ThinAOP對(duì)外的接口,對(duì)于需要使用AOP的類,需要使用ProxyFactory來生成相應(yīng)的代理類。
ProxyFactory類中只有一個(gè)靜態(tài)方法,就是用來生成動(dòng)態(tài)代理類的。
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中定義了四個(gè)類:
- ExceptionMetadata:用于保存程序中exception的信息
- MethodMetadata :用于保存程序中方法的信息(目前只有方法名)
- ParameterMetadata:用于保存程序中方法的參數(shù)信息
- ResultMetadata:用于保存程序中方法的返回值信息
通過上面定義的四個(gè)類,我們可以看出此AOP框架值主要是針對(duì)方法這個(gè)級(jí)別的攔截。即攔截方法在執(zhí)行前,執(zhí)行后,異常時(shí)的操作。
這四個(gè)類非常簡(jiǎn)單,只是定義了一些屬性。
4. ThinAOP的介紹-InvokeContext
保存了必須的上下文信息,也就是上面定義的那些Metadata
5. ThinAOP的介紹-DynamicProxyGenerator
這個(gè)類是整個(gè)框架的核心,用來生成動(dòng)態(tài)代理,在代理中完成對(duì)方法的攔截操作,并在攔截后注入自己的代碼。
核心方法是GenerateType,根據(jù)現(xiàn)有type生成新的type
public Type GenerateType()
{
// 構(gòu)造程序集
BuildAssembly();
// 構(gòu)造模塊
BuildModule();
// 構(gòu)造類型
BuildType();
// 構(gòu)造字段
BuildField();
// 構(gòu)造函數(shù)
BuildConstructor();
// 構(gòu)造方法
BuildMethods();
Type type = _typeBuilder.CreateType();
// 將新建的類型保存在硬盤上(如果每次都動(dòng)態(tài)生成,此步驟可省略)
_assemblyBuilder.Save(AssemblyFileName);
return type;
}
其中的Emit代碼,我已經(jīng)寫了相應(yīng)的C#代碼。
Emit代碼類似IL,我也是先寫C#代碼,然后用ILSpy轉(zhuǎn)成IL代碼,然后參照IL代碼來寫的Emit部分代碼。
6. ThinAOP的介紹-AspectAttribute
這個(gè)類定義了一系列的Attribute,方便于定義攔截操作。
主要定義了3中攔截操作:分別是執(zhí)行前攔截 ,執(zhí)行后攔截,異常時(shí)攔截
[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.
整個(gè)框架的實(shí)現(xiàn)參考了博客園里很多文章,這里就不一一列舉了。
除了ThinAOP的框架外,我還寫了了一個(gè)使用這個(gè)框架的例子,具體請(qǐng)參見提供的附件:ThinAOP


浙公網(wǎng)安備 33010602011771號(hào)