hBifTs

山自高兮水自深!當塵霧消散,唯事實留傳.荣辱不惊, 看庭前花开花落; 去留随意, 望天上云展云舒.

导航

Aop.NET 简单说明.

Posted on 2004-04-20 16:38  hbiftsaa  阅读(3762)  评论(5编辑  收藏  举报
不知道Aop.NET的朋友可以看我前面的帖子"博客园的开源项目: Aop.NET DotNetAOP"

由于现在这个项目刚刚开始,文档/使用说明等都不是很完善,可能通过查看源代码中的TestCase可以了解一些使用方法.
所以我在这里先说一下关于Aop.NET-我们博客园的开源项目的一些使用说明等...btw,关于Aop的情况各位可以去Google上搜索.

最近一次更新时间: Wednesday, May 12, 2004 10:35:00 AM

1, Aop.NET是基于DynamicProxy的方式实现函数Hook的. 原理和我以前的帖子"DynamicPorxy for .NET "是一样的.所不同的是我修改了代码实现,让DynamicProxy直接从目标类继承而来,并且Hook此类中的所有Public Virtual 函数(注:只有这种函数才可能被Hook).

2, 由于是继承而来,并且在继承后的实际类的构造函数中调用AopBaseHandle类中的BeforeInvoke/AfterInvoke函数...此构造函数的实际代码如下:
class Real : Target{
    public Real(...){
              AopBaseHandle.BeforeInvoke(...);
              Base();
              AopBaseHandle.AfterInvoke(...);
    }
}
注: 由于后面的版本修改了IFilter接口..去掉了CtorBegin/CtorEnd,而且Ctor的调用与Method的调用统一在AopBaseHandle.Invoke中了,所以在自定义AopHandle的时候注意判断Method是否为Constructor的情况..

3,由于函数中很可能出现这样的情况:
class T{
  public virtual A(){}
  pubic virtual B(){ A();}
}
要使函数B调用函数A时也能够被Hook.所以在实际类中的实际代码如下:
 public virtual RealFunc(...){ base.Func();}
RealFunc是实际类中的真正要调用的函数,在Aop.NET的实现代码中,此函数名为目标函数的MethodInfo.GetHashCode();
 public virtual Func(...){
       AopBaseHandle.Invoke(...);
}
此函数是与目标类的同名函数.
通过用户调用目标类的中函数,使程序跳到AopBaseHandle.Invoke函数中,在此函数中,通过使用Type.GetMethod(methodname)的方法得到真正的RealFunc,再调用实际函数.
注: Invoke函数中的MethodInfo method为原函数的MethodInfo,只有通过这个才能得到原函数中的Attributes.

4,在AopBaseHandle.Invoke(...)中,调用真正函数前,先调用BeforeInvoke(...),再调用真正函数,最后调用AfterInvoke(...)

5,用户如果要自定义AopHandle,可能从AopBaseHandle进行派生,或是直接从IProxyInvocationHandler接口进行派生.
注: Invoke的实现代码中的Method不要搞错了~

6,用户要增加一个Filter(Aspect),要从IFilter接口继承而来.IFilter定义了两个函数,BeforeInvoke/AfterInvoke. 分别在函数的调用前/调用后执行.

7,BeforeInvoke和AfterInvoke函数的参数为从IAopContext继承而来的AopBaseContext,用来将实际调用的函数的信息,像 Target,MethodInfo,Parameters,等等传进去.同时,为了方便实现应用(比如,判断某种情况,如果不行,就不调用实际函数),所以加入了bool Cancel.同时,如果函数有返回值,为了保证栈平衡,所以同时也得设置 ReturnValue...
Exception参数主要用于AfterInvoke,当函数调用出现异常,那么AopBaseHandle会将些异常传给AfterInvoke函数,由它们来处理这个异常...

8.现在使用Aop.NET有两个类厂来产生实际对象.一个是AopFactory,使用的时候把想要加入的Aspect类(实现IFilter)通过Create函数加入进去.另一个是AopXmlFactory,它是直接解析Xml配置文件来完成增加Pointer的.

9,在最新的Aop.NET v0.2 beta(Sourceforge.net上面有)中,增加了使用Xml文件进行配置的功能,并且是针对具体的函数进行Hook的.同时在此版本中加入了一个AopFilterCollection类,这个类是用来加入Filter的.比如你想对这个类(AopTest)的函数加上权限检查功能,只要把你自定义的权限类(AclFilter)从IFilter接口继承,实现接口函数.加入到AopFilterCollection中,程序在执行时会自动调用你加入的这个权限类.可以加入多个,执行顺序和你加入(Add)的顺序一样.
Xml文件的格式如下:
<?xml version="1.0" encoding="utf-8" ?>
<AopNET>
<AspectAssembly Name="TestNAopXml.exe">   这个Name是你想要加入的权限类(AclFilter)所在的程序集的文件的路径
 <AspectClass Name="TestNAopXml.AopTest" Enable="true">   这个Name是你想要把事务加上去的类(AopTest)的 命名空间+类名称
  <CrosscutClass Name="TestNAopXml.myfilter" Enable="false" >   这个Name就是你想要加入的权限类(AclFilter) 的 命名空间+类名称
  <PointMethod Name="Run" Enable="true" />  具体要Hook的函数..Enable是指是否Hook,默认(不存在)是启用的(true)
  <PointMethod Name="AopTest" Enable="true"/> Hook构造函数,直接调用IFilter中的BeforeInvoke/AfterInvoke.
  </CrosscutClass>
 </AspectClass>
</AspectAssembly>
</AopNET>
程序中具体使用时,得在程序的配置文件的路径是有两个方法,一个就是由App.config中的<appSettings>指定的: <add key="TestNAopXml.exe" value="..\..\NAop.xml"/> key值为当前处理的Type所在的程序集的文件名, value是配置文件的路径,另一个就是当前目录 + 当前被Hook的Type所在的程序集的文件名+.xml 的文件.
AopXmlFactory首先查找App.Config中有没有此字段,如果没有,才用第二种,,使用时请注意..
具体可以参考源代码,下载包中有源文件
注: 要使用Xml配置文件,你得使用AopXmlFactory类来产生实际的对象.注意不要搞错了..

10.增加了Xml配置文件修改自动更新的功能.这样子就可以在程序运行过程中动态修改Aspect

先就这么多吧,后面增加的功能再修改这个文档.