博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于.net的aop实现技术
阅读量:4315 次
发布时间:2019-06-06

本文共 2943 字,大约阅读时间需要 9 分钟。

前言

在笔者的《面向对象的应用服务层设计》一文中,笔者讨论了软件系统中设计应用服务层所需要考虑的问题,以及系统分层的基本思考方法。这些讨论作关注的问题,都是系统中纵向的层次的划分。然而,在设计软件系统的时候,我们不仅仅要考虑纵向的关系,很多时候,我们还需要关注所谓的“横切关注点”的问题,例如,存在于系统每个部分的日志记录、安全性验证等。aop(面向方面编程)的出现,便是为了解决这些“横切关注点”的问题。
虽然aop目前还不是如oop般非常成熟,但是,也已经有数个支持aop的产品问世,其中比较有名的有aspectj,aspectwerkz等,这些产品都基于java平台。在.net平台上,也有一些实现,如loom等,但是,相对于java平台的实现,这些实现都还很不成熟,功能也比较弱,使用上也不是很方便。因此,笔者在.net平台下自己实现了一个轻量级的aop框架,现在拿出来同大家共同探讨。
在本文中,笔者将首先归纳一下目前实现aop的基本手段,然后,给出一个已经实现的aop的范例(websharpaspect),并提供全部源代码,这是一个轻量级的aop实现,虽然目前功能还不是很强大,实现也比较简单,但是,他已经可以完成大部分我们所需要的aop功能,你可以在项目中直接使用他。重要的是,其中展示了在.net环境下实现aop的一些技术和思路,笔者也希望通过提供源代码的方式,能够对大家学习aop有所助益。
实现aop的方法
实现aop的关键,是拦截正常的方法调用,将我们需要额外附加的功能透明的“织入”到这些方法中,以完成一些额外的要求。从总体方法上来说,织入的方法有两大类:静态织入和动态织入。
静态织入方法,一般都是需要扩展编译器的功能,将需要织入的代码,通过修改字节码(java)或者il代码(.net)的方法,直接添加到相应的被织入点;或者,我们需要为原来语言添加新的语法结构,从语法上支持aop。aspectj就是采用的这种方式。使用这种方式来实现aop,其优点是代码执行的效率高,缺点是实现者需要对虚拟机有很深的了解,才能够做到对字节码修改。由于织入方法是静态的,当需要添加新的织入方法时,往往需要重新编译,或者说运行字节码增强器重新执行静态织入的方法。当然,在.net平台上,我们也可以使用emit提供的强大功能来实现这一点。另外,字节码增强器带来了很大的不透明性,程序员很难直观的调试增强后的字节码,因此很多程序员总是在心理上抵制这种字节码增强器。
动态织入的方法,具体实现方式就有很多选择了。在java平台上,可以使用proxy模式,或者定制classloader来实现aop功能。在.net平台上,要实现aop的动态织入,归纳起来,可以采用以下几种方法:
l 使用contextattribute和contextboundobject来对对象的方法进行拦截。关于contextattribute的具体使用方法,读者可以参考msdn等相关资料。
l 使用emit来,在运行时刻动态构建被织入代码后的类,当程序调用被织入类时,实际上调用的是被修改后的类。loom使用的就是这种方式,但是,个人认为,loom目前的实现非常生硬,其可扩展性和灵活性都不是很好。
l 使用proxy模式。这也是本文将详细介绍的方法。
l 当然,在asp.net项目中,我们还有一种选择,就是使用httphandler和httpmodule来对自定义对asp.net页面的访问,加入一些我们需要的处理。关于如何使用httphandler和httpmodule的内容,可以参考笔者的文章《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的方法。

转载于:https://www.cnblogs.com/tuyile006/archive/2011/11/02/2233552.html

你可能感兴趣的文章
MySql command line client 命令系列
查看>>
内置函数2
查看>>
扩展 IEnumerable<T>,让它根据另一个集合的顺序来排列
查看>>
mvc4.0添加EF4.0时发生编译时错误
查看>>
第16月第12天 CABasicAnimation 旋转加速
查看>>
Linux下查看Python安装了哪些脚本模块
查看>>
ERROR- 开发常见error
查看>>
Servlet 中文乱码问题及解决方案剖析
查看>>
OO第四次博客总结
查看>>
集合—ArrayList
查看>>
web前台设计技术
查看>>
Ubuntu14.04 在右键中添加 在终端中打开
查看>>
Eclipse代码规范工具-Checkstyle安装和使用
查看>>
【读书笔记】 nginx 负载均衡测试
查看>>
JQUERY1.9学习笔记 之属性选择器(一) 前缀选择器
查看>>
TortoiseSVN显示图标不正常
查看>>
joj1020
查看>>
javascript模式——Decorator
查看>>
junit测试简单实例
查看>>
迷宫问题,POJ-3984
查看>>