【原创】颠覆C#王权的“魔比斯环” — 实现AOP框架的终极利器
上一篇 / 下一篇 2008-09-30 19:53:13 / 个人分类:微软技术
ITPUB个人空间}H'X-?2q
时间要追溯到2005年。那时正在做硕士论文。题目是“AOP framework for .net”。这个AOP框架将使用C#2.0来实现。这当然没什么令人惊奇的。从理论上说,任何开发语言都可以实现AOP框架。但要按着AOP联盟的规范实现这个AOP框架,大多数的开发语言并不能很容易地完成这项任务。
微软公司在我们心目中是强大的,而出自于微软的C#自然也会被认为是强大的。使用C#几乎可以很容易地完成大多数的应用程序(包括桌面、Web、移动等)。但要用C#来实现标准的AOP框架却不是那么容易,甚至有点强人所难。这到底是为什么呢?
一、 AOP的概念和原理
AOP(Aspect
Oriented Programming)的中文意思是“面向方面编程”。它是10年前由施乐公司提出的。这种技术并不是一种新的编程技术,和OOP(Object Oriented Programming)并不是平级的。它只是OOP的一种扩展。
一个典型的软件系统由核心功能和系统功能组成。所
谓核心功能就是和这个系统相关的业务功能,如在mail服务器中的核心功能是接收和发送电子邮件。系统功能则可以看成是系统的可选功能,如日志、安全等。
如果没有了这些功能,mail服务器仍可以照常工作,只是不太安全了,并且无法查找以往的记录。实现这些系统功能,一般的作法是将系统功能的代码和核心功
能的代码混在一起。这样做不仅加大了系统设计和实现的难度,而且使设计系统核心功能的程序员必须要考虑这些系统的功能,分散了他们的注意力。
由 于在软件开发中遇到以上问题,人们开始设想是否能将软件中的核心功能和系统功能分开,达到单独设计、实现、维护的目的。于是就有人提出在设计和实现时单独 进行,当编译时将单独编写的系统功能的代码织入(weaves)到核心功能的代码中,将代码织入的工具叫织入器(weaver)。这种思想经过长期的实 践,就逐渐形成了AOP的核心思想,同时也形成了AOP最早的一个实现:AspectJ。
AOP构建在已有的技术基础之上,同时提供了自己的一套额外机制,也就是Aspect机制,对系统进行描述、设计和实现。AOP要保证这些机制在概念上简洁,执行效率高。其基本思想是通过分别描述系统的不同关注点(属性或者兴趣)及其关系,以一种松耦合的方式实现单个关注点,然后依靠AOP环境的支撑机制,将这些关注点组织或编排成最终的可运行程序。关注点包括普通关注点和系统的贯穿特性。通常可以使用传统的结构化方法和面向对象方法提供的机制,对普通关注点进行处理;使用Aspect机制,对贯穿特性进行处理。系统的贯穿特性范围包括了从高层的关注目标,比如安全和服务质量,到低层的关注目标比如缓存处理等。贯穿特性可以是功能性的,比如事务规则,也可以是非功能的,比如同步和交易管理等。AOP将传统方法学中分散处理的贯穿特性实现为系统的一类元素—Aspect,并将它们从类结构中独立了出来,成为单独的模块。
为了支持上述的系统实现和运行过程,AOP系统首先必须提供一种声明Aspect的机制,包括Aspect如何声明,连接点(Aspect代码与其它代码的交互点)如何定义,Aspect代码如何定义,Aspect的参数化程度和可定制性等。其次,需要提供一种将Aspect代码和基础代码组合编排(Weaving)在一起的机制,包括定义编排语言和规则,解决Aspect之间潜在的冲突,为组装和执行建立外部约束等。最后,必须有生成可运行系统的实现机制,包括系统提供什么组合机制,是编译时刻静态组装,还是运行时动态组装;对程序单元分别进行编译的模块化编译机制;对AOP机制和现有系统兼容性的规约;对组装结果的验证机制等。
二、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的代码如下: