赞助商
PIAB Overview

一、Business Logic 和 Infrastructure Logic的分离

对于任何一个企业级应用的开发人员来说,他们编写的代码不仅仅是处理单纯的业务逻辑,同时还需要处理很多的非业务方面的逻辑,比如:Caching、Transaction Enlist、Authorization、Auditing、Exception Handling、Logging、Validation甚至是Performance Counter。我习惯把这些非业务逻辑成为Infrastructure Logic。由于这些Infrastructure Logic通常根据具体的需求注入的具体的业务逻辑的执行中,所以又被更多地成为Crosscutting Concern。

如果按照传统的OO的编程方式,我们通常将这些Business Concern和Crosscutting Concern糅合在一起,从而导致了某种意义的紧耦合。这种紧耦合在一个大型的企业级应用可能是会给应用的可扩展性带来致命的影响。所以必须以某种方式实现Business Concern和Crosscutting Concern的分离,这通常是AOP实现的目标。

举个简单的例子,我们现在有如下一个简单的订单处理操作,可能具体的业务逻辑很简单。但是此操作面临的非业务逻辑可能有很多。比如:·        在处理之前进行Authorization,确定当前的用户是否具有此操作的权限。
·        Auditing,记录处理的用户、处理时间等等。
·        Transaction Enlist,将所有Data Access操作纳入同一个Transaction,保证数据的一致性。
·        进行Exception Handling。
·        如果出现异常,记录日志。

上面的这些可以体现在线面的Code中:
  1. public void ProcessOrder(Order order)

  2.         {

  3.             Authorize();

  4.             Audit();

  5.             using (TransactionScope scope = new TransactionScope())

  6.             {

  7.                 try

  8.                 {

  9.                     OrderDataAccess();             
  10.                 }

  11.                 catch (Exception ex)

  12.                 {

  13.                     HandleExceptoin(ex);

  14.                     Log();

  15.                 }

  16.             }
  17.         }
复制代码
可以看到上面这么多行代码中,和业务相关的就一行而已。虽然对这些非业务逻辑的实现通常通过调用一个封装好的方法或者组件完成,你往往只需要Copy Paste就可以了,但是将如此众多的Infrastructure Logic和Business Logic按照这样的方式组合在一起有很多的隐患。 


  • 首先,将一些公共的Source code进行大规模的复制不能保证其同一性和正确性。我个人觉得,对于一个程序原来说,如果你频繁地使用到Ctrl + C和Ctrl + V,你应该想到你的代码需要重构。
  • 其次,Infrastructure Logic和Business Logic这种耦合性导致对Infrastructure Logic的变动将获导致Source Code的改变。
  • 此外,这样的编程方式增加了程序员的压力,可能对于一个相对Junior的程序员来说,可能根本不知道这个Infrastructure Logic的具体作用何在,而实际上对于最终的程序员来讲,这些应该是对他们透明的。

所以我们需要寻求某种方式将这些Infrastructure Logic注入到某个具体的操作中,而不需要将所有的逻辑实现在具体的方法定义中。比如:你可以通过配置文件进行配置,你也可以通过添加Attribute一声明的方式来实现。而这一切都可以通过Enterprise Library的PIAB来实现。

二、PIAB(Policy Injection Application Block)Overview

PIAB在Enterprise Library 3.0中被引入(注意:不要把PIAB和DIAB混淆,DIAB-Dependence Injection Application Block将在Enterprise Library 4.0中被引入,个人觉得这将又是一个具有重大意义的AB,它的使用将会极大的减轻模块或组件的依赖关系,在Software Factory中已经有了广泛的应用)。PIAB提供了一种简单而有效的方式是你能够将你所需的非业务逻辑的Crosscutting concern注入到的某个方法的Invocation stack中。比如可以在方法的调用前注入Auditing的执行,在成功调用后执行Transaction commit的调用,在出现异常时进行Exception Handling的处理。

对于PIAB来说,Policy的意思是:“将对应的处理操作注入到对应的方法调用”。这实际上包含两方面的内容:要注入怎样的处理操作和如何与具体的方法匹配。前者封装在一个称作CallHandler的对象中,而匹配关系通过另一个称作MatchingRule的对象来表现。所以可以说Policy= CallHandler+MatchingRule。

PIAB给我们提供了很多系统自定义CallHandler,在一般情况下它能满足我们绝大部分的需求,比如: 


  • Enterprise Library Security Application Block的Authorization来实现。
  • CachingCallHandler:将方法返回值作为Value、参数列表作为Key存入Cache,如果下次出现相同参数列表的调用,则直接将Cache中的值返回,从而免去了再次执行方法对性能的影响。像一般的Cache处理一样,你也可以设置Cache的过期时间。
  • ExceptionCallHandler:通过调用Enterprise Library Exception Handing Application Block实现对一异常处理的支持。
  • LogCallHandler:通过调用Enterprise Library Logging Application Block进行日志的处理。
  • ValidationCallHandler:进行参数的验证等功能,该CallHandler依赖于Enterprise Library Validation Application Block。
  • PerformanceCounterCallHandler。

至于MatchingRule,他实际上是定义了一种如何将CallHander和对应的Method进行匹配的规则。同样的,一系列的MatchingRule被定义出来,比如:基于Assembly的MatchingRule将CallHandler匹配到某个Assembly的所有对象上面;基于Custom Attribute的MatchingRule通过声明在某个元素上的某个Attribute进行匹配。此外还有基于NameSpace、Method Signature、等等的MatchingRule。

如何现有的CallHandler和MatchingRule不能满足你具体的要求,你还可以定义Custom CallHandler或者 Custom MatchingRule。在后续的部分将会介绍一个完整的定义Custom CallHandler的例子。
赞助商
赞助商
TOP