您好,欢迎访问三七文档
EnterpriseLibraryPolicyInjectionApplicationBlock之一在过去的半年里,定期或者不定期地写点东西已经成为了我的一种习惯。可是最近两个月来一直忙于工作的事情一直足够的时间留给自己,虽然给自己列了很长一串写作计划,可是心有余而力不足。这一段工作主要是帮助公司开发一套分布式的开发框架,对一些技术和设计方法有了一些新的认识。这两天的工作主要是如何把EnterpriseLibraryV3.1的PIAB(PolicyInjectionApplicationBlock)引入到我们自己的框架中,为次对PIAB进行了一些研究,借此机会与大家一起分享。PartI:PIABOverviewPartII:PIAB设计和实现原理PartIII:PIAB扩展-如何创建CustomCallHandler一、BusinessLogic和InfrastructureLogic的分离对于任何一个企业级应用的开发人员来说,他们编写的代码不仅仅是处理单纯的业务逻辑,同时还需要处理很多的非业务方面的逻辑,比如:Caching、TransactionEnlist、Authorization、Auditing、ExceptionHandling、Logging、Validation甚至是PerformanceCounter。我习惯把这些非业务逻辑成为InfrastructureLogic。由于这些InfrastructureLogic通常根据具体的需求注入的具体的业务逻辑的执行中,所以又被更多地成为CrosscuttingConcern。如果按照传统的OO的编程方式,我们通常将这些BusinessConcern和CrosscuttingConcern糅合在一起,从而导致了某种意义的紧耦合。这种紧耦合在一个大型的企业级应用可能是会给应用的可扩展性带来致命的影响。所以必须以某种方式实现BusinessConcern和CrosscuttingConcern的分离,这通常是AOP实现的目标。举个简单的例子,我们现在有如下一个简单的订单处理操作,可能具体的业务逻辑很简单。但是此操作面临的非业务逻辑可能有很多。比如:·在处理之前进行Authorization,确定当前的用户是否具有此操作的权限。·Auditing,记录处理的用户、处理时间等等。·TransactionEnlist,将所有DataAccess操作纳入同一个Transaction,保证数据的一致性。·进行ExceptionHandling。·如果出现异常,记录日志。上面的这些可以体现在线面的Code中:publicvoidProcessOrder(Orderorder){Authorize();Audit();using(TransactionScopescope=newTransactionScope()){try{OrderDataAccess();}catch(Exceptionex){HandleExceptoin(ex);Log();}}}可以看到上面这么多行代码中,和业务相关的就一行而已。虽然对这些非业务逻辑的实现通常通过调用一个封装好的方法或者组件完成,你往往只需要CopyPaste就可以了,但是将如此众多的InfrastructureLogic和BusinessLogic按照这样的方式组合在一起有很多的隐患。首先,将一些公共的Sourcecode进行大规模的复制不能保证其同一性和正确性。我个人觉得,对于一个程序原来说,如果你频繁地使用到Ctrl+C和Ctrl+V,你应该想到你的代码需要重构。其次,InfrastructureLogic和BusinessLogic这种耦合性导致对InfrastructureLogic的变动将获导致SourceCode的改变。此外,这样的编程方式增加了程序员的压力,可能对于一个相对Junior的程序员来说,可能根本不知道这个InfrastructureLogic的具体作用何在,而实际上对于最终的程序员来讲,这些应该是对他们透明的。所以我们需要寻求某种方式将这些InfrastructureLogic注入到某个具体的操作中,而不需要将所有的逻辑实现在具体的方法定义中。比如:你可以通过配置文件进行配置,你也可以通过添加Attribute一声明的方式来实现。而这一切都可以通过EnterpriseLibrary的PIAB来实现。二、PIAB(PolicyInjectionApplicationBlock)OverviewPIAB在EnterpriseLibrary3.0中被引入(注意:不要把PIAB和DIAB混淆,DIAB-DependenceInjectionApplicationBlock将在EnterpriseLibrary4.0中被引入,个人觉得这将又是一个具有重大意义的AB,它的使用将会极大的减轻模块或组件的依赖关系,在SoftwareFactory中已经有了广泛的应用)。PIAB提供了一种简单而有效的方式是你能够将你所需的非业务逻辑的Crosscuttingconcern注入到的某个方法的Invocationstack中。比如可以在方法的调用前注入Auditing的执行,在成功调用后执行Transactioncommit的调用,在出现异常时进行ExceptionHandling的处理。对于PIAB来说,Policy的意思是:“将对应的处理操作注入到对应的方法调用”。这实际上包含两方面的内容:要注入怎样的处理操作和如何与具体的方法匹配。前者封装在一个称作CallHandler的对象中,而匹配关系通过另一个称作MatchingRule的对象来表现。所以可以说Policy=CallHandler+MatchingRule。PIAB给我们提供了很多系统自定义CallHandler,在一般情况下它能满足我们绝大部分的需求,比如:EnterpriseLibrarySecurityApplicationBlock的Authorization来实现。CachingCallHandler:将方法返回值作为Value、参数列表作为Key存入Cache,如果下次出现相同参数列表的调用,则直接将Cache中的值返回,从而免去了再次执行方法对性能的影响。像一般的Cache处理一样,你也可以设置Cache的过期时间。ExceptionCallHandler:通过调用EnterpriseLibraryExceptionHandingApplicationBlock实现对一异常处理的支持。LogCallHandler:通过调用EnterpriseLibraryLoggingApplicationBlock进行日志的处理。ValidationCallHandler:进行参数的验证等功能,该CallHandler依赖于EnterpriseLibraryValidationApplicationBlock。PerformanceCounterCallHandler。至于MatchingRule,他实际上是定义了一种如何将CallHander和对应的Method进行匹配的规则。同样的,一系列的MatchingRule被定义出来,比如:基于Assembly的MatchingRule将CallHandler匹配到某个Assembly的所有对象上面;基于CustomAttribute的MatchingRule通过声明在某个元素上的某个Attribute进行匹配。此外还有基于NameSpace、MethodSignature、等等的MatchingRule。如何现有的CallHandler和MatchingRule不能满足你具体的要求,你还可以定义CustomCallHandler或者CustomMatchingRule。在后续的部分将会介绍一个完整的定义CustomCallHandler的例子。三、GetStarted经过上面对PIAB的介绍,我想大家对PIAB使用的目标又一个简单的认识,为了加深大家的映像,在本节中,我们做一个简单的Walkthrough,做一个简单的使用PIAB的例子。在这个例子通过PIAB实现两个主要的功能:Caching和Logging。为了简单起见,我们使用一个ConsoleApplication来实现这样一个例子。我们假设的一个场景时处理一个订单并将处理后的订单返回。StepI:创建一个ConsoleApplication,并添加下面连个DllReference.Microsoft.Practices.EnterpriseLibrary.PolicyInjectionMicrosoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlersStepII:编写OrderProcessing的代码:publicclassOrderProcessor:MarshalByRefObject{publicOrderProcess(Orderorder){Console.WriteLine(OrderProcessor.Process()isinvocated!);returnorder;}}publicclassOrder{}至于为什么要继承MarshalByRefObject将会在后面对PIAB的实现原理中介绍。将对OrderProcessor的调用写在Main()。staticvoidMain(string[]args){OrderProcessorprocessor=PolicyInjection.CreateOrderProcessor();Orderorder=newOrder();processor.Process(order);processor.Process(order);}StepIII:创建app.config,并通过EnterpriseLibraryConfigurationConsole进行配置:1、添加一个LoggingApplicationBlock2、按照相同的方式添加一个PolicyInjectionApplicationBlock,然后再PIAB节点添加一个Policy。在该Policy下的MatchRules节点下创建一个MethodNameMatchingRule(该MatchingRule根据Methodname进行CallHandler的匹配)。对该MatchingRule进行如下的配置:那么该Policy的CallHandler将会自动应用到Methodname为Process的方法上。3、在Policy下的Handlers节点添加两个CallHandler:CachingHandler和LoggingHandler。保持CachingHandler的默认配置,按如下进行LogingHandler的配置:通过上面的配置,我们将会得到如下的Configuration:ConfigurationconfigSectionssectionname=policyInjectiontype=Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.PolicyInjectionSettings,Microsoft.Practices.EnterpriseLibrary.PolicyInjection,Version=3.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a/sectionname=loggingConfigurationtype=Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings,Microsoft.Practices.EnterpriseLibrary.Logging,Version=3.
本文标题:Enterprise Library Policy Injection Application Bl
链接地址:https://www.777doc.com/doc-3564296 .html