一切福田,不離方寸,從心而覓,感無不通。

微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录

 

      在前面的Part3中,我介绍Policy Injection模块中内置的Call Handler的使用方法,今天则继续介绍Call Handler——Custom Call Handler,通过建立Custom Call Handler来实现项目中的用户操作日志的记录,具体的代码可以在项目中EntLib.Helper项目下找到,如下图:

pic67本文将从Custom Call Handler两种方式来介绍:Attribute方式和Configuration方式。

 

一、核心代码

建立Custom Call Handler则需要有以下几个步骤:

1、建立一个类实现接口ICallHandler。

2、根据具体需求建立对应Attribute类或为Custom Call Handler实现特性[ConfigurationElementType(typeof(CustomCallHandlerData))]

首先来介绍下具体的核心代码,由于我是要实现用户的操作日志,则需要对用户的对数据的增删改以及一些特殊的操作进行记录,如:登录,

1、首先需要建立一张表用于存放用户操作记录:

2、建立一个名为UserLogCallHandler的类来实现接口ICallHandler,实现其中的方法Invoke(具体的拦截操作方法)和属性Order,具体代码如下(关键处我都写好注释了

这段代码主要部分就是具体的Invoke方法实现,这个方法有2个参数:

input,这个参数中封装了已拦截的方法、方法的参数等有用的信息

getNext,一个委托,用于调用拦截的方法,通过这个委托我们可以很好的控制我们需要在拦截了具体方法后如何进行具体的业务逻辑操作。

通过getNext()(input, getNext); 这段代码即可完成对方法的调用,这样可以根据具体需求决定在调用方法前还是方法后进行具体操作。

由于我这边是要实现一个用户操作记录,那么我要知道一些具体的信息:是谁在什么时候对什么数据做了操作,这边我需要获取3个参数:具体的操作人、操作的数据及具体描述。

首先来看下第一个参数:

具体的操作人,由于这个项目采用的是cookies来记录当前的登录用户,所以我可以直接从cookies中获取当前登录的人,具体可以查看代码69-71行。

操作的数据,这边我在这个Call Handler中建立了一个ParameterName属性用来指定记录所拦截的方法中存放所操作数据的参数名,具体可以查看代码74-86行。

由于指定了具体的参数名,我们则需要根据参数获取具体数据值,我们来看下增删改的方法签名:

int Add(Student student); 
bool Update(Student student); 
bool Delete(int id);

可以看到,我们都可以从这3个方法获取到用户具体操作的数据标识,如Student.Id和id,这样我们只需变通一下,在具体的类中,如Student中,重写ToString方法,返回具体的ID即可,代码如下:

这样,我们在Call Handler中我们就可以根据参数名获取到具体操作的数据了(如果需要详细描述具体的数据的话则需要更复杂的设计了,这边就不深入了),代码如下:

具体描述,这个我也是建立一个Message数据,用于存放操作的具体描述。

特殊情况,当然操作日志也不可能就仅仅增删改3种情况,就比如登录,注销,这种情况则只需指定具体的消息即可,参数名无需指定,如果还有更加特殊的情况则需要根据具体需求来更改这边的设计,我这边只是给出个最基本的。

 

二、Attribute实现

在完成了核心代码后,我们则可以根据需求建立Attribute拦截还是Configuration拦截了。

实现Attribute拦截,需要建立一个类,实现HandlerAttribute类,实现其中的CreateHandler方法,用于调用具体的Call Handler方法,具体代码如下:

这个特性类就比较简单了,不过还需要在Call Handler中进行处理,增加一个构造函数,接收从Attribute中传递过来的参数:

 

三、Configuration方式

如果要实现可以通过企业库配置工具进行配置Custom Call Handler的话,则需要对Call Handler增加一个特性:

[ConfigurationElementType(typeof(CustomCallHandlerData))]

然后新增一个构造函数

完成以上2步我们就可以通过企业库配置工具进行配置了,见下图:

pic68

 

四、具体使用

在完成了Call Handler的代码编写和登录拦截配置后,我们就可以进行使用了,我这边更改了项目的结构,建立了一个IBLL的接口层,现有的BLL层的类则实现IBLL层中接口,而且由于Policy Injection模块要实现AOP,则具体类必须继承自MarshalByRefObject或实现一个接口(如果不清楚可以查看Part1),所以为了项目的各模块解耦、方便Policy Injection对具体类的创建和未来Unity介绍做铺垫则创建了IBLL层。(具体可以参看项目代码)

由于建立了IBLL层,则表示层的代码则需要发生变化,所有BLL层创建都需要通过PolicyInjection.Create方法来创建,具体代码如下:

这样,当我们运行代码后,进入数据库查看就可以看,操作日志已经被记录下来了。

上面说的是通过Configuration方式来进行操作日志记录,如果我们想通过Attribute方式来记录日志消息,则需要到具体的BLL层进行操作,代码如下:

注意:这边需要为项目引用Microsoft.Practices.Unity.Interception,因为Call Handler的Attribute是继承自HandlerAttribute,这个HandlerAttribute就是存放于Microsoft.Practices.Unity.Interception,否则自定义的Call Handler Attribute将无法显示出来。

这样,更新下学生信息后,我们可以就可以看到具体的操作日志了,见下图:

pic69

 

以上就是本文的所有内容,主要介绍了如何通过Custom Call Handler实现用户操作日志记录,如果有什么不对,欢迎大家指出,谢谢:)

至此,Policy Injection模块的介绍也结束了,下面将开始介绍企业库中使用最广泛的IOC容器——Unity,敬请期待!

转自:http://www.cnblogs.com/kyo-yo/archive/2010/10/13/Learning-EntLib-Ninth-Use-PolicyInjection-Module-AOP-PART4-Call-Handler-To-Build-User-Logging.html