且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

更新时间:2022-09-05 17:27:30

代理对象(Proxy Object)会通过Handler链定位到真实对象(Real Object),而Policy则被注入到代理对象和真实对象中。整个流程如图:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

 

我个人对Policy Injection Application Block使用的看法是:

用户先创建一个代理,用这个代理间接操作实体,在调用实体的方法或者成员属性时可以透明的触发一系列设置好的Handler(如日记记录,身份验证等),并且只需要修改相应的配置文件就能快速更改Handler链.(因为是个人看法,也许不太准确,官方解释在此 http://msdn.microsoft.com/en-us/library/ff647463.aspx)

Authorization横切关注点(Cross-Cutting Concerns)的处理方式如图所示:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

 

 

PIAB目前预定义的Handler包括Validation Handler、Logging Handler、Exception Handling Handler、Authorization Handler、Caching Handler。这些Handler与Enterprise Library中的其他Application Block几乎是一一对应的。事实上,权限认证、日志、异常处理、缓存等,恰恰都是AOP技术最重要的关注点。在February 2007 CTP版本之前的Application Block,实际上已经具备了AOP的雏形。然后,由于它在“横切”与“注入”方面的缺乏,始终无法达到AOP所要求的重用目的。Policy Injection Application Block正好弥补了这样的缺憾。还是和以前一样,用实例来说话吧,因为这个模块功能较多,程序较大,在文章最后我也打包了供大家下载研究.

下面我们就来剖析Policy Injection Application Block:

首先分析一下需求:

1.建立一个财务管理器

2.提供有3个角色:

  a)  Teller:允许调用存款,取款,查账的方法

  b)  Assistant:允许调用查账方法

  c)  Janitor:无任何权限,做测试用

3. 创建几个用户,分配到这3个角色中,用户调用方法的代码中不用判断当前用户隶属于什么角色,即判断过程透明化

4.调用方法的信息以及错误信息自动写入日志,并且日记写入过程透明化

先说说按照传统的编程方法,我们假设有一个用户Charlie是属于Janitor角色的,当他按下程序中的查账按钮的时候应该被提示不允许,并把该错误写入日志中,则程序可能就会如下所示:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block
privatevoid button1_Click(object sender,EventArgs e)
{
//先进行角色验证
if(Charlie.所属角色 != Assistant ||Charlie.所属角色 != Teller)
{
//如果不符合条件,则报错并写入日志
MessageBox.Show("身份验证失败");
Log.Write(
"身份验证失败");
}
else
{
//获取余额
double balance = GetCurrentBalance();
MessageBox.Show(balance.ToString());
}
}
Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

要注意的是,只有红色部分的代码真正实现了业务逻辑,而之前蓝色部分都是对身份的判断以及错误的处理,当你的程序出现越来越多类似的业务操作时,你会发现你需要大量拷贝此处的代码,这就已经说明你的程序需要重构了,试想一下,如果此时需要再多验证一个角色,或者要更换日志的处理方案时,你将需要重新将整个程序中出现相同业务逻辑的代码重新更新一次,这显然是不被允许的.于是Policy Injection Application Block此时就粉墨登场啦!

看看用了Policy Injection Application Block之后的代码风格:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block
privatevoid button1_Click(object sender,EventArgs e)
{
  try
{
 
double balance = GetCurrentBalance();
MessageBox.Show(balance.ToString());
}
  catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

如何?简单吧,程序中只有关乎业务逻辑的代码,没有其他多余的非业务逻辑代码了,然而实现的功能是和之前的代码一样喔!想知道怎么实现的吗?请看下面的教程吧.(教程中的源代码我会打包提供给大家下载的,请在文章最后寻找下载链接)

1.首先我们需要一个BankAccount类,用于提供财务管理需要的属性以及方法,其中我们给这个类添加上一个balance私有属性用于表示余额.还提供了Deposit, Withdraw, GetCurrentBalance方法,实现存款,取款和查询余额的功能.该类的代码如下所示:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block代码

2.运行EntLibConfig.exe, 选择Blocks菜单 ,单击Add Policy Injection Settings .点击Policies面板右上角的加号按钮AddPolicy,将Name属性修改为MyPoliy:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

3.在Policies面板上右键Add Matching RulesAdd Member Name Matching Rule,点击创建好的MemberName Matching Rule面板上Member Names项目右侧的加号按钮,将BankAccount类中的成员方法名称(Deposit, Withdraw, GetCurrentBalance)添加进去,表示我们的MyPoliy决策中要对这些方法进行匹配,如果被程序调用或者出现错误异常,就会进行相应的处理.

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

4.于是,我们顺理成章的要添加一定的错误处理机制, 在Policies面板上右键—Add HandlersAdd Logging Call Handler,并设置为文本记载日志的方式,日志模块的详细介绍在此不多讲,大家可以参考我之前写的文章.至此,我们已经完成了成员方法被调用以及错误异常的处理机制了.日志文本格式化设置如下:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block日志文本格式化

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

5.好,我们再看看需求,我们还需要创建3个角色和一些用户.在此就顺便讲解EL中的Application模块吧,因为它的功能很简单,就不专门做一个教程了,在此我们用它来配置角色和用户.选择Blocks菜单 ,单击Add Application Settings .点击Setting面板右上角的加号,添加一些用户,分别是

Key:   User:Alice       Value:Teller

Key:   User:Bob         Value:Assistant

Key:   User:Charlie   Value:Janitor

其中Key的值中User:为前缀,表示添加为用户,后面跟着的是用户名,而Value值表示该用户所隶属的角色,在程序中我们就可以写个函数从该模块中获取到用户名和角色啦(此处的用户名和角色一般是存储在数据库或者XML文件中,在此用Application模块完全是想借此机会讲解该模块而已,大家可以选用其他的方案):

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

6.好了,有了用户和角色,接下来要配置验证模块了.这就需要我们之前讲过的Security模块了,该模块的详细介绍在我之前的文章中已经写出,在此不多讲,只讲应用.

选择Blocks菜单 ,单击Add Security Settings .点击Authorization Providers面板右上角的加号按钮Add Authorization ProvidersAdd AuthorizationRule Provider. 

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

7.在Authorization Rule Provider面板上右键—AddAuthorization Rules,添加一个验证规则.在此我们设置3中验证规则,将 BankAccount类中的存款,取款,查账权限分别分配给刚刚建立的3个角色中,设置如下:

Name: Deposit                        Rule Expression: R:Teller

Name: Withdraw                    Rule Expression: R:Teller

Name: GetCurrentBalance    RuleExpression: R:Teller OR R:Assistant

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

8.设置好了验证规则模块,当然要想办法和我们的Poliy模块关联起来啦,因为是身份验证,所以匹配范围应该在整个Namespace,因此让我们回到Poliy模块, 点击Policies面板右上角的加号按钮Add Policy,将Name属性修改为Authorize,再在Authorize面板上右键Add Matching RulesAdd Namespace Matching Rule,并添加一个匹配对象,Name设置为test(请确保和你要匹配的Namespace名称相同):

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

9.在Authorizes面板上右键Add HandlersAdd Authorization Call Handler,属性设置如下图所示:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

10.好了,至此我们也将验证规则模块和Poliy模块绑定起来了,下面可以运行程序进行验证了,程序已打包在下方可下载,我只是将演示效果截图给大家看看,详细内容请参看源代码:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

再点击查看日志,会发现之前的操作都被记录下来了:

Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block

好了, PolicyInjection Application Block模块就讲到这,大家有什么好的想法可以给我留言~

下载源代码:  

点击此处\(^  ^)/




本文转自黄聪博客园博客,原文链接:http://www.cnblogs.com/huangcong/archive/2010/06/06/1752491.html,如需转载请自行联系原作者