Enterprise Library Policy Injection Application BlockWord格式.docx
- 文档编号:18800266
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:53
- 大小:844.27KB
Enterprise Library Policy Injection Application BlockWord格式.docx
《Enterprise Library Policy Injection Application BlockWord格式.docx》由会员分享,可在线阅读,更多相关《Enterprise Library Policy Injection Application BlockWord格式.docx(53页珍藏版)》请在冰豆网上搜索。
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)Overview
PIAB在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.PolicyInjection
Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers
StepII:
编写OrderProcessing的代码:
publicclassOrderProcessor:
MarshalByRefObject
{
publicOrderProcess(Orderorder)
Console.WriteLine("
OrderProcessor.Process()isinvocated!
"
);
returnorder;
}
publicclassOrder
{ }至于为什么要继承MarshalByRefObject将会在后面对PIAB的实现原理中介绍。
将对OrderProcessor的调用写在Main()。
staticvoidMain(string[]args)
{
OrderProcessorprocessor=PolicyInjection.Create<
OrderProcessor>
();
Orderorder=newOrder();
processor.Process(order);
}
StepIII:
创建app.config,并通过EnterpriseLibraryConfigurationConsole进行配置:
1、添加一个LoggingApplicationBlock
2、按照相同的方式添加一个PolicyInjectionApplicationBlock,然后再PIAB节点添加一个Policy。
在该Policy下的MatchRules节点下创建一个MethodNameMatchingRule(该MatchingRule根据Methodname进行CallHandler的匹配)。
对该MatchingRule进行如下的配置:
那么该Policy的CallHandler将会自动应用到Methodname为Process的方法上。
3、在Policy下的Handlers节点添加两个CallHandler:
CachingHandler和LoggingHandler。
保持CachingHandler的默认配置,按如下进行LogingHandler的配置:
通过上面的配置,我们将会得到如下的Configuration:
Configuration<
configSections>
<
sectionname="
policyInjection"
type="
Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.PolicyInjectionSettings,Microsoft.Practices.EnterpriseLibrary.PolicyInjection,Version=3.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
/>
loggingConfiguration"
Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings,Microsoft.Practices.EnterpriseLibrary.Logging,Version=3.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
<
/configSections>
policyInjection>
policies>
<
addname="
Policy"
>
<
matchingRules>
<
addtype="
Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MemberNameMatchingRule,Microsoft.Practices.EnterpriseLibrary.PolicyInjection,Version=3.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
name="
MemberNameMatchingRule"
<
matches>
<
addmatch="
Process"
ignoreCase="
false"
/matches>
/add>
/matchingRules>
handlers>
addexpirationTime="
00:
05:
00"
Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.CachingCallHandler,Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers,Version=3.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
CachingHandler"
addlogBehavior="
After"
beforeMessage="
=================End================="
afterMessage="
================Begin================"
eventId="
0"
includeParameterValues="
true"
includeCallStack="
includeCallTime="
priority="
-1"
severity="
Information"
Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.LogCallHandler,Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers,Version=3.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
LoggingHandler"
categories>
Audit"
/categories>
/handlers>
/policies>
/policyInjection>
loggingConfigurationname="
LoggingApplicationBlock"
tracingEnabled="
defaultCategory="
General"
logWarningsWhenNoCategoriesMatch="
listeners>
addsource="
EnterpriseLibraryLogging"
formatter="
TextFormatter"
log="
Application"
machineName="
listenerDataType="
Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData,Microsoft.Practices.EnterpriseLibrary.Logging,Version=3.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
traceOutputOptions="
None"
Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener,Microsoft.Practices.EnterpriseLibrary.Logging,Version=3.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
name="
FormattedEventLogTraceListener"
/listeners>
formatters>
addtemplate="
Timestamp:
{timestamp}Message:
{message}Category:
{category}Priority:
{priority}EventId:
{eventid}Severity:
{severity}Title:
{title}Machine:
{machine}ApplicationDomain:
{appDomain}ProcessId:
{processId}ProcessName:
{processName}Win32ThreadId:
{win32ThreadId}ThreadName:
{threadName}ExtendedProperties:
{dictionary({key}-{value})}"
type="
Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter,Microsoft.Practices.EnterpriseLibrary.Logging,Version=3.1.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
/formatters>
categorySources>
addswitchValue="
All"
name="
/categorySources>
specialSources>
allEventsswitchValue="
AllEvents"
notProcessedswitchValue="
UnprocessedCategory"
errorsswitchValue="
LoggingErrors&
amp;
Warnings"
/errors>
/specialSources>
/loggingConfiguration>
<
/configuration>
我们现在来运行以下程序:
从输出的结果可以看出,虽然我们在Main()两次调用了Process方法,但是真正执行的数次只有一次。
这是Caching所致,第一次调用PIAB将返回值存入Cache,该CacheEntry的Key为参数Order对象。
第二次调用由于传入的参数相同,所有直接将上次的结果返回。
上面我看到了Caching的效果,现在我们在看看Logging。
默认情况下,Loggingentry被写入EventLog。
下图就是我们写入的Log。
EnterpriseLibraryPolicyInjectionApplicationBlock之二
在前面一篇文章中,我对EnterpriseLibrary中的PIAB(PolicyInjectionApplicationBlock)作了简单的介绍。
在这篇文章主要谈谈我个人对PIAB设计和实现原理的一些理解。
在介绍过程中,我尽量采用由浅入深出的方式,同时结合例
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Enterprise Library Policy Injection Application Block
![提示](https://static.bdocx.com/images/bang_tan.gif)
链接地址:https://www.bdocx.com/doc/18800266.html