基于.Net的AOP实现技术

来源:互联网 发布:什么是网络营销策划 编辑:程序博客网 时间:2024/05/21 15:32

基于.NetAOP实现技术

前言

在笔者的《面向对象的应用服务层设计》一文中,笔者讨论了软件系统中设计应用服务层所需要考虑的问题,以及系统分层的基本思考方法。这些讨论作关注的问题,都是系统中纵向的层次的划分。然而,在设计软件系统的时候,我们不仅仅要考虑纵向的关系,很多时候,我们还需要关注所谓的“横切关注点”的问题,例如,存在于系统每个部分的日志记录、安全性验证等。AOP(面向方面编程)的出现,便是为了解决这些“横切关注点”的问题。

虽然AOP目前还不是如OOP般非常成熟,但是,也已经有数个支持AOP的产品问世,其中比较有名的有AspectJAspectWerkz等,这些产品都基于Java平台。在.Net平台上,也有一些实现,如LOOM等,但是,相对于Java平台的实现,这些实现都还很不成熟,功能也比较弱,使用上也不是很方便。因此,笔者在.Net平台下自己实现了一个轻量级的AOP框架,现在拿出来同大家共同探讨。

在本文中,笔者将首先归纳一下目前实现AOP的基本手段,然后,给出一个已经实现的AOP的范例(WebsharpAspect),并提供全部源代码,这是一个轻量级的AOP实现,虽然目前功能还不是很强大,实现也比较简单,但是,他已经可以完成大部分我们所需要的AOP功能,你可以在项目中直接使用他。重要的是,其中展示了在.Net环境下实现AOP的一些技术和思路,笔者也希望通过提供源代码的方式,能够对大家学习AOP有所助益。

实现AOP的方法

实现AOP的关键,是拦截正常的方法调用,将我们需要额外附加的功能透明的“织入”到这些方法中,以完成一些额外的要求。从总体方法上来说,织入的方法有两大类:静态织入和动态织入。

静态织入方法,一般都是需要扩展编译器的功能,将需要织入的代码,通过修改字节码(Java)或者IL代码(.Net)的方法,直接添加到相应的被织入点;或者,我们需要为原来语言添加新的语法结构,从语法上支持AOPAspectJ就是采用的这种方式。使用这种方式来实现AOP,其优点是代码执行的效率高,缺点是实现者需要对虚拟机有很深的了解,才能够做到对字节码修改。由于织入方法是静态的,当需要添加新的织入方法时,往往需要重新编译,或者说运行字节码增强器重新执行静态织入的方法。当然,在.Net平台上,我们也可以使用Emit提供的强大功能来实现这一点。另外,字节码增强器带来了很大的不透明性,程序员很难直观的调试增强后的字节码,因此很多程序员总是在心理上抵制这种字节码增强器。

动态织入的方法,具体实现方式就有很多选择了。在Java平台上,可以使用Proxy模式,或者定制ClassLoader来实现AOP功能。在.Net平台上,要实现AOP的动态织入,归纳起来,可以采用以下几种方法:

l         使用ContextAttributeContextBoundObject来对对象的方法进行拦截。关于ContextAttribute的具体使用方法,读者可以参考MSDN等相关资料。

l         使用Emit来,在运行时刻动态构建被织入代码后的类,当程序调用被织入类时,实际上调用的是被修改后的类。LOOM使用的就是这种方式,但是,个人认为,LOOM目前的实现非常生硬,其可扩展性和灵活性都不是很好。

l         使用Proxy模式。这也是本文将详细介绍的方法。

l         当然,在ASP.Net项目中,我们还有一种选择,就是使用HTTPHandlerHTTPModule来对自定义对ASP.Net页面的访问,加入一些我们需要的处理。关于如何使用HTTPHandlerHTTPModule的内容,可以参考笔者的文章ASP.Net中自定义Http处理及应用之HttpHandler篇》,以及ASP.Net中自定义Http处理及应用之HttpModule篇》

下面,我们来探讨如何使用Proxy模式,在.Net平台上实现一个可用的AOP框架。

第一个例子

首先,我们来看看WebsharpAspect的使用效果。我们可以使用以下步骤来完成我们的第一个例子的编写:

1、  VisualStudio中新建一个控制台应用程序,把Websharp.Aspect.dll添加入引用。

2、  添加一个类,命名为FirstAspect,并使他实现IAspect接口,添加代码如下:

public class FirstAspect : IAspect

     {

         public void Execute(object[] paramList)

         {

              Console.WriteLine("FirstAspect is called");

         }

     }

3、  添加一个BusinessClass类,模拟具体的业务逻辑类,使这个类继承AspectObject类,并添加AspectManaged特性,然后添加两个方法,代码如下:

[AspectManaged(true)]

     public class BusinessClass : AspectObject

     {

         public BusinessClass(){}

         public void OutputMethod()

         {

              Console.WriteLine("OutputMethod()");

         }

         public void GetString()

         {

              Console.WriteLine("GetString()");

         }

     }

4、  为项目添加一个App.config配置文件,,并且添加以下内容:

<?xmlversion="1.0"encoding="utf-8"?>

<configuration>

     < configSections >

<sectionname="Websharp.Aspects"type="Websharp.Aspect.AspectConfigHandler,Websharp.Aspect"/>

     </ configSections >

    

     < Websharp.Aspects >

         < Aspect type ="WeaveTest.FirstAspect,WeaveTest" deploy-model ="Singleton"

            pointcut-type="Method|Construction"action-position="Both"match="*,*"/>

     </ Websharp.Aspects >

</configuration>

5、  Main方法中添加如下代码:

public class MainClass

     {

         [STAThread]

         static void Main ()

         {

              BusinessClass cls=new BusinessClass();

              cls.OutputMethod();

              cls.GetString();

              Console.ReadLine();

         }

     }

运行以上代码,其结果如下:

       可以看到,FirstAspect如我们所预期的那样,成功的拦截了BusinessClass的方法。

   源代码和全文见:http://www.websharp.org 也可以从http://www.uml.org.cn/dvbbs6.0.0/index.asp  下载全部源代码

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 鸡蛋吃多过敏了怎么办 想把衣服换颜色怎么办 衣服用84洗坏了怎么办 衣服用84洗花了怎么办 衣服用84洗黄了怎么办 白色衣服用84漂黄了怎么办 84把衣服泡黄了怎么办 84把衣服洗花了怎么办 衣服用84洗掉色怎么办 被84褪色的衣服怎么办 衣服被84烧红了怎么办 84溅到衣服上边怎么办 84把衣服泡花了怎么办 衣服颜色洗旧了怎么办 蒙版画笔用不了怎么办 眼睛小血管破裂出血怎么办 雅漾喷头坏了怎么办 一夜都是浅睡眠怎么办 注塑机合不了膜怎么办 吸了塑料烧焦味怎么办 热熔的管漏水怎么办 45岁了月经不来怎么办 吃了芒果身上痒怎么办 10个月宝宝上火怎么办 1个月的宝宝上火怎么办 2个月的婴儿上火怎么办 1岁宝宝不吃奶粉怎么办 奶水不够宝宝又不吃奶瓶怎么办 13岁脸上长粉刺怎么办 脸敷面膜过敏了怎么办 婴儿面膜是假的怎么办 一贴面膜就过敏怎么办 一敷面膜就过敏怎么办 敷了面膜后过敏怎么办 脸做面膜过敏了怎么办 二十几年的疤痕怎么办 三星c5听筒坏了怎么办 胖子减肥后皮肤松弛怎么办 小婴儿脸上长癣怎么办 痘痘里面有脓怎么办 牛仔外套买大了怎么办