技术开发 频道

颠覆C#王权的“魔比斯环”



    二、C#限制颇多,实现AOP框架困难重重

    虽然诞生于10多年前的AOP技术在近几年开始逐渐流行起来。有一些应用很广的软件或框架,如JBoss、Spring,都使用了AOP技术。但这些AOP技术大多是基于java的。如AspectJ、JBoss AOP和Spring AOP。但是AOP技术在.net环境下应用得很少,其于.net的AOP 框架也不多。形成这种情况的原因很多。众所周知,实现AOP一般有两种方法。一种是利用动态代理或其它技术在程序运行时对方法等信息进行监控(如JBoss AOP和Spring AOP),即动态AOP。另外一种是直接在编译器中支持,就象AspectJ。但这种做法实现的难度较大,大多数AOP框架的实现都是采用了第一种方法。而动态代理技术在.net中(不管是VB.net和C#都一样)实现是非常困难的,在.net中并不象java提供了动态代理实现机制。在.net中要想实现动态代理必须得直接使用IL(Intermediate Language)写代码,这样就必须对IL有非常深入的了解。

   由于要在C#中实现这个AOP框架,因此,我不可能再自己做个编译C#编译器甚至虚拟机。所以只能使用动态代理的方式来实现。但使用动态代理需要解决两个问题。
    1. 如何动态生成代理类。
    2. 如何拦截构造方法。

   1. 如何动态生成代理类
   在阐述问题之前,先让我们看一看什么叫代理类。代理类也是普通的类。只是这个类要继承于被代理的类。而且在代理类中的方法要覆盖父类中的方法。如类Class1的代码如下:

class Class1 { public virtual void Method1() {...} public virtual String Method2() {... return s;} ... ... public Class1(String s){...} }
    上面的Class1有一系列的virtual方法,并且有一个构造方法。下面让我们来编写一个代理Class1的代理类ProxyClass:

class ProxyClass : Class1 { public override void Method1(){ base.Method1(); ... } public override String Method2(){ String s = base.Method2(); ... return s} public Class2(String s) : base(s) {...} }
    从ProxyClass类可以看出,在使用下面代码创建Class1对象后,仍然会得到Class1类中相应方法执行后的结果:
Class1 class1 = new ProxyClass(“hello world”);
    虽然上面的代码可能大多数程序员都能理解(就是多态调用),但实际上这种代码对基于动态代理技术的AOP框架是毫无用处的。之所以叫动态代理,就是在程序执行时自动生成代理类。而上面的代码是静态地写到程序中的,在编译后无法更改。也许有人会说,根据Class1可以自动生成ProxyClass类的源码,然后在内存或硬盘上编译再调用不就可以了!这种做法可以是可以,但效率却非常的低。大家可以想象,如果每执行一个方法,就生成一堆C#源代码,再编译,恐怕C#就比脚本语言还慢了。
看到这些,也许那些C#或.net高手会说,直接生成MSIL不就行了。但你要知道,虽然MSIL没有汇编复杂,可对于大多数程序员来说,是可望而不可及的。因此,这个技术问题就成为实现AOP框架的第一个大障碍。
0
相关文章