1. Aspect#
在所有的方案中,不谈技术能力的高低,只从其定位和文档质量来说
,Aspect#给我的感觉是定位最明确,文档质量也最高。
首先,它的定位非常明确,也因此他能够被castle项目收录为子
项目。实际上,Aspect#就是castle.dynamicp
roxy的扩展,而castle.dynamicproxy得本质
就是通过reflection,emit,delegate
,在运行时动态的为非sealed类的virtual方法生成pr
oxy类。Aspect#则是在此基础上定义了一套configu
ration language,并以此为基础,方便用户使用dynamicpr
oxy来minin和intercept。而Aspect
#的限制也就是dynamicproxy天然的限制
,因为要继承原来的类,只有"非sealed类的virtual方
法"才能被intercept,这是不可逾越的限制。 aop.net原来的实现,恐怕也是相同的思路。(还有一点值得一提的,castle
.dynamicproxy的官方首页有博客源zhengyulu
兄和iaxes兄在博客园介绍castle.dynamicpro
xy使用的文章链接哟~~,请看:
http://www.castleproject.org/index.php/DynamicProxy )
当然,从技术的角度来讲,dynamicproxy一点也不先进
(相较于rail这样的il级别织入来讲),不过
,他也有其天然的优势:一是他的原理非常易于理解;二是易于使用
;三是他基于一种假设,那就是OOD中,正确的设计往往会广泛的使
用接口来降低耦合、实现各种pattern,而很大部分重要的业务
代码的实现都是virtual方法,因此,虽然dynamicpr
oxy看是限制多多,实际上还是很有必要的一种机制,用户面很广
;四基于和castle项目的天然结合,用户对Aspect
#的信任自然是无用质疑的。这些,都使得Aspect
#必然会成功!
还有就是它的文档质量和示例代码非常简单易懂,他的two minute tutorial确实做到了two minute就会使用,这个也是值得其他AOP方案大大学习的地方。
2. AspectDNG
AspectDNG和Aspect#其实有一点是非常相似的
,那就是他也和Aspect#那样基于另一个类库rail
,rail是干什么用的呢?简单的说,rail是用来的做静态织入
用的,你给我任何一个assembly,只要没有混淆
,我都可以用rail在il的级别对原有的代码作修改
,修改当然就包括了扩展、合并、intercept
、delete等等,总之,从修改原有程序集的角度来讲
,理论上是无所不能的。AspectDNG基于rail
,并以在此基础上定义了一套xml格式的ILML语言
,能够将原有的程序集拆散成ILML格式,方便用户的修改
,修改过后,再拼装回去,就成了新的程序集,因此
,AspectDNG的定位也就是非常明确的,那就是对静态程序集
的修改和扩展,并为静态织入旧的程序集提供了很多方便的类库
。但是记住,AspectDNG只提供静态织入,这就是它的定位
。还有像Eos,和他也是类似的,只不过Eos提供了一个非常类似
AspectJ的语法,但本质上,还是差不多的静态il级别织入。
不过,AspectDNG的文档可就比Aspect#差了点
,代码中还处处是法文单词和注释,这就太不友好了
,好在它的示例还算简单清晰,而rail这个类库本身的文档和示例
还算是比较简明易懂的,也因此,还不算太难用。
评论
以上两者是现有的.NET下的AOP实现的佼佼者,分别是两个很明确的思路,都很好的利用了现有的第三方类库作为基础
。
值得思索的是,其他的方案都没有这两个方案成功,不仅仅是因为其他
方案提供的configuration方式没有这两个方案完善
,而且因为,其他的方案,凡是希望自己实现一个地位相当于cast
le.dynamicproxy或rail这样的类库的
,往往容易陷进某个深渊。因为,要实现一个非常好的,功能强
,又稳定,又值得信任的这样的类库,真不是一件容易的事
。
从底层技术的角度讲,主流的AOP Framework一般有如下三种织入方式:
1、基于dynamicproxy的运行时interceptio
n;
2、基于IL级别的静态织入;
3、基于IL级别的动态载入时织入;
从Configuratuion方式的角度讲,主流的AOP Framework一般有如下四种配置方式:
1、类似Aspect#的独立的自定义Configuration
格式;
2、类似AspectDNG的,基于XML的Configura
tion格式;
3、基于Custom Attribute的Configuration格式;
4、类似AspectJ的特定语言扩展及相应的Compiler;
//文章结束