Enterprise Library 异常处理应用程序块简介
本文档维护在:http://wiki.entlib.net.cn/EntlibHelp31ExceptionHandlingApplicationBlock.ashx。
Enterprise Library 异常处理应用程序块让开发人员和策略制定者为处理发生在企业应用程序的所有架构层的异常创建一致的策略。它以下列方式进行:
使用异常处理程序
异 常处理应用程序块被设计为以支持包含在应用程序组件中的 catch 语句的典型代码。代替在遍及应用程序组件中的相同的 catch 块中重复这些代码(如记录异常日志信息),应用程序块允许开发人员封装这些逻辑为可重用的异常处理程序。异常处理程序是封装了异常处理逻辑并实现了名为 IExceptionHandler 的异常处理应用程序块接口的 .NET 类。异常处理应用程序块包含四个异常处理程序:
用户可以通过实现自己的处理程序来扩展异常处理应用程序块。配置控制台提供了配置异常处理应用程序块以使用定制的处理程序的能力。开发人员不必修改应用程序块源代码或者重新生成应用程序块。
使用异常策略
异 常处理应用程序块让你用命名策略来关联异常类型。(关于异常类型的更多信息,请参见 .NET System.Exception 类。)可以通过使用配置控制台来完成它。策略指定在应用程序块处理特定异常类型时执行的异常处理程序。可以将这些处理程序串在一起以致于在关联的异常类型 被处理时执行一系列的异常处理程序。下面是命名策略的一些示例,以及它们可能提供什么的描述:
示例应用程序代码
下面的代码展示了在异常发生时如何执行命名为“Data Access Policy”的策略。
读者需求
此指南的目的是软件构架、软件开发人员和策略制定者。要从本指南中获取所有好处,你需要理解下列技术:
新的特性
异常处理应用程序块的 2007年5月的发行包含了下列改进:
系统需求
运行异常处理应用程序块的需求如下:
异常处理应用程序块依赖
异常处理应用程序依赖于 Enterprise Library 中的其他代码:
修改异常处理应用程序块的推荐方法是使用 Enterprise Library 配置控制台。
异常处理应用程序块文档
除介绍以外,文档还包括下列主题:
更多信息,请参见下面的 Microsoft patterns & practices 指南:
根据场景组织这些任务的目的是给代码一些环境上下文。代替显示一个孤立的方法组,而没有它们最好被使用在哪儿的意义,场景提供了用于代码的设置,并且描述了类似于必须处理异常的应用程序的开发人员的解决方案。
场景如下:
异 常处理应用程序块最好用于需要统一和灵活的处理异常的过程的情况。例如,可能在应用程序的架构的特定层中的所有组件要一致的异常处理过程。还有,修改安全 或者其他的操作问题的原因,可能要能够在需要时修改策略,而不要求应用程序源代码的改变。异常处理应用程序块,结合 Enterprise Library 配置控制台,可以完成这二个任务。
例如,可以使用配置控制台来定义使用用不包含敏感信息的版本来替换包含敏感信息的异常的处理程序。应用程序块然后实现此策略跨越组件,组件包含指定使用此策略的代码。
异常处理应用程序块不限于跨层的应用程序,它也可以被用于特殊的应用程序中。例如,可以定义记录异常信息日志的策略或者显示异常信息给用户。
另 一种情况是,策略不用修改应用程序的代码而被配置。这使它们在新的情况发生时易于维护或改变。注意,在所有的情况中,将仅能使用应用程序块完成特定地异常 处理并且不与应用程序的业务逻辑交叉的任务。例如,可以移除记录异常日志或者在另一个异常中包装一个异常的处理程序,而不影响如更新客户数据库的基本功 能。
图 1 展示了跨层和应用程序单一组件异常处理的例子。
发生在数据访问层的异常被记录日志,然后被包装在提供对调用层来说更有意义的信息的异常中。在业务组件层,异常在被传播前被记录日志。任何发生在业务组件层的包含敏感信息的异常,将被不再包含这些信息的异常所替换,这些将被发送到用户界面(UI)层,然后显示给用户。
不使用异常处理应用程序块,用于数据访问组件的典型异常处理代码看起来像如下示例。
代码类似于这将在所有完成不同数据访问查询的方法中重复。要改变异常处理代码的行为,就必须更新包含此代码的每个方法。
换句话说,使用异常处理应用程序块,同样的应用程序将有下面的代码。
异常处理代码的行为决定于名为 Data Access Policy 的异常处理策略。应用程序将有用于 Data Access Policy 的配置设置,以指明传递到用于异常处理应用程序块的日志异常处理的类型为 System.Exception 的异常。要修改异常处理代码的行为,只需要修改配置信息即可,而不需要更新应用程序的源代码。
异 常处理应用程序块是异常处理恢复代码的补充,它没有代替恢复代码。如果因为非常不常见的原因发生异常,它会无法温和的恢复应用程序,并且结束启动它的工作 单元。然而,有时是可以恢复的。一个例子是,一个异常的发生是因为文件被锁定,恢复代码可以指示应用程序在等待一段时间后重试文件。在这种情况中,异常处 理的恢复代码将在应用程序内部实现,它不能被实现为被异常处理应用程序块所使用的处理程序。这是因为它要求访问局部变量、参数和其他的环境数据。这些数据 在由异常处理应用程序块运行的处理程序作用域之外并且无法访问。
Enterprise Library 异常处理应用程序块让开发人员和策略制定者为处理发生在企业应用程序的所有架构层的异常创建一致的策略。它以下列方式进行:
- 支持在应用程序的所有架构层的异常处理,不仅限于服务接口边界。
- 允许异常处理策略被定义和维护在管理层,以致于可能是系统管理员也可能是开发人员的策略制定者可以定义如何处理异常。他们可以维护和修改异常处理的规则而不需要修改应用程序块的代码。
- 提供了常用的异常处理功能,例如记录异常信息为日志的功能、通过用另一个异常替换原始异常来隐藏敏感信息的功能,以及通过包装原始异常到另一个异常中来维护异常的上下文环境信息的功能。这些功能被封装在名为异常处理程序的 .NET 类中。
- 可以组合异常处理程序和生成预期的响应到一个异常中,例如,在用另一个异常替换原始信息后即记录日常信息。
- 让开发人员创建自己的异常处理程序。
- 以一致的风格调用异常处理程序。这意味着异常处理程序可以用于应用程序内和跨应用程序的多个地方。
使用异常处理程序
异 常处理应用程序块被设计为以支持包含在应用程序组件中的 catch 语句的典型代码。代替在遍及应用程序组件中的相同的 catch 块中重复这些代码(如记录异常日志信息),应用程序块允许开发人员封装这些逻辑为可重用的异常处理程序。异常处理程序是封装了异常处理逻辑并实现了名为 IExceptionHandler 的异常处理应用程序块接口的 .NET 类。异常处理应用程序块包含四个异常处理程序:
- Wrap handler。此异常处理程序用一个异常包装另一个异常。
- Replace handler。此异常处理程序用一个异常替换另一个。
- Logging handler。 此异常处理程序格式化异常信息,如消息和堆栈跟踪。然后日志处理程序将此信息给 Enterprise Library 日志应用程序块以使它可以被发布。
- Fault Contract Exception Handler。此异常处理程序为用于 Windows Communication Foundation (WCF) 服务边界而设计,并从异常创建一个新的 Fault Contract 。
用户可以通过实现自己的处理程序来扩展异常处理应用程序块。配置控制台提供了配置异常处理应用程序块以使用定制的处理程序的能力。开发人员不必修改应用程序块源代码或者重新生成应用程序块。
使用异常策略
异 常处理应用程序块让你用命名策略来关联异常类型。(关于异常类型的更多信息,请参见 .NET System.Exception 类。)可以通过使用配置控制台来完成它。策略指定在应用程序块处理特定异常类型时执行的异常处理程序。可以将这些处理程序串在一起以致于在关联的异常类型 被处理时执行一系列的异常处理程序。下面是命名策略的一些示例,以及它们可能提供什么的描述:
- Base policy。此策略记录异常并重新抛出原始异常。
- Secure policy。此策略记录异常,用一个定制异常替换原始异常,然后抛出新的异常。
- Expressive policy。此策略包装原始异常到另一个异常,然后抛出新的异常。
示例应用程序代码
下面的代码展示了在异常发生时如何执行命名为“Data Access Policy”的策略。
C#
try
{
//执行代码。
}
catch(Exception ex)
{
bool rethrow = ExceptionPolicy.HandleException(ex, " Data Access Policy");
if (rethrow)
throw;
}
Visual Basic
Try
' 执行代码。
Catch ex As Exception
Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, " Data Access Policy")
If (rethrow) Then
Throw
End If
End Try
读者需求
此指南的目的是软件构架、软件开发人员和策略制定者。要从本指南中获取所有好处,你需要理解下列技术:
- Microsoft Visual Studio 2005 开发系统
- Microsoft .NET Framework 2.0。
新的特性
异常处理应用程序块的 2007年5月的发行包含了下列改进:
- 异常处理应用程序块可用于在 WCF 应用程序的服务边界上实现异常屏蔽。ExceptionShieldingAttribute 可以被定义在一个服务实现类上以在服务边界上调用异常策略。FaultContractExceptionHandler 可以用于映射异常到 Fault Contracts 以防止敏感信息被返回给不信任的调用者。
- ExceptionPolicy.HandleException 方法包含了一个新的重载,它调用了异常策略在一个输出参数中返回了结果异常,而不是抛出结果异常。
- Wrap 和 Replace 异常处理程序包含了另外的配置属性,它允许在外部资源中指定异常消息,而不是直接放在配置文件中。这种能力可以用来支持异常消息的本地化。
系统需求
运行异常处理应用程序块的需求如下:
- Microsoft Windows XP Professional, Windows Server 2003 或 Windows Vista 操作系统
- Microsoft .NET Framework 2.0 或者 3.0。 .NET Framework 3.0 是 WCF 异常屏蔽所需要的。
- Microsoft Visual Studio 2005 开发系统 (任何下列版本):
- Microsoft Visual Studio 2005 标准版
- Microsoft Visual Studio 2005 专业版
- Microsoft Visual Studio 2005 软件开发人员团队版
- Microsoft Visual Studio 2005 软件测试人员团队版
- Microsoft Visual Studio 2005 软件架构师团队版
- Microsoft Visual Studio 2005 团队套件
异常处理应用程序块依赖
异常处理应用程序依赖于 Enterprise Library 中的其他代码:
- 内核库功能。Enterprise Library 内核提供了如度量和配置等服务,它是所有 Enterprise Library 应用程序块的共享依赖。内核库的功能被包含在程序集 Microsoft.Practices.EnterpriseLibrary.Common.dll 中。
- ObjectBuilder 子系统。ObjectBuilder 子系统完成所有重复的、必要的用于创建和销毁对象实例的任务,同时提供了调试的灵活性。Enterprise Library 将 ObjectBuilder 子系统用于如注入配置到程序块类中以及连接度量类到应用程序块中等任务。ObjectBuilder 子系统被包含在程序集 Microsoft.Practices.ObjectBuilder.dll 中。
- 如果要使用日志应用程序块记录异常日志,将需要 Microsoft.Practices.EnterpriseLibrary.Logging.dll 和 Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.dll 。
- 另 外,异常处理应用程序块可能依赖于其他代码,包括日志应用程序异常块和数据访问应用程序块。异常处理应用程序块在使用日志处理程序时需要日志应用程序块。 如果配置日志应用程序块使用数据库跟踪监听程序,它将需要数据访问应用程序块。更多信息,请参见日志应用程序块的文档和数据访问应用程序块的文档。
修改异常处理应用程序块的推荐方法是使用 Enterprise Library 配置控制台。
异常处理应用程序块文档
除介绍以外,文档还包括下列主题:
- 使用异常处理应用程序块开发应用程序。此主题解释了如何在应用程序中使用异常处理应用程序块。开发任务的细节子主题解释了如何确定适当的 异常处理策略,如何指定不同的处理活动,以及如何发送异常到异常处理块。关键场景子主题展示了在自己的应用程序中使用异常处理应用程序块的不同方式。
- 异常处理块的设计。此主题解释了应用程序块的设计考虑和在那些考虑后的相关事物。
- 扩展和修改异常处理应用程序块。此主题解释了如何通过添加定制的处理程序和格式化程序来扩展应用程序块。它还给出了一些如何修改源代码的建议。
- 部署和操作。此主题解释了如何部署和更新应用程序块程序集。
- 异常处理应用程序块快速入门。这解释了如何安装和配置快速入门应用程序,以及包括了一系列的漫游,漫游示范了如何合并常用异常处理操作到应用程序中。
更多信息,请参见下面的 Microsoft patterns & practices 指南:
- Application Architecture for .NET: Designing Applications and Services
- Exception Management Architecture Guide
1.1 - 场景和目标
异常处理应用程序块为处理开发人员在编写使用异常处理的应用程序时所面对的绝大多数常见任务而设计。这些任务根据场景进行了组织。每个场景给出了一个真实世界解决方案的示例、讨论了解决方案所需要的异常处理功能,以及展示了完成任务的代码。根据场景组织这些任务的目的是给代码一些环境上下文。代替显示一个孤立的方法组,而没有它们最好被使用在哪儿的意义,场景提供了用于代码的设置,并且描述了类似于必须处理异常的应用程序的开发人员的解决方案。
场景如下:
- 记录异常日志
- 包装异常
- 替换异常
- 传播异常
- 显示用户友好消息
- 通知用户
- 协助支持人员
- 在 WCF 服务边界上屏蔽异常
1.2 - 何时使用异常处理应用程序块
关于如何开发异常管理策略的信息,请参见Exception Management Architecture Guide。尽管它没有专门讨论异常处理应用程序块,但是它可以帮助你定义清晰、一致的方式处理异常。使用异常管理应用程序块来帮助实现自己的策略。异 常处理应用程序块最好用于需要统一和灵活的处理异常的过程的情况。例如,可能在应用程序的架构的特定层中的所有组件要一致的异常处理过程。还有,修改安全 或者其他的操作问题的原因,可能要能够在需要时修改策略,而不要求应用程序源代码的改变。异常处理应用程序块,结合 Enterprise Library 配置控制台,可以完成这二个任务。
例如,可以使用配置控制台来定义使用用不包含敏感信息的版本来替换包含敏感信息的异常的处理程序。应用程序块然后实现此策略跨越组件,组件包含指定使用此策略的代码。
异常处理应用程序块不限于跨层的应用程序,它也可以被用于特殊的应用程序中。例如,可以定义记录异常信息日志的策略或者显示异常信息给用户。
另 一种情况是,策略不用修改应用程序的代码而被配置。这使它们在新的情况发生时易于维护或改变。注意,在所有的情况中,将仅能使用应用程序块完成特定地异常 处理并且不与应用程序的业务逻辑交叉的任务。例如,可以移除记录异常日志或者在另一个异常中包装一个异常的处理程序,而不影响如更新客户数据库的基本功 能。
图 1 展示了跨层和应用程序单一组件异常处理的例子。
图 1 异常处理策略的例子 |
发生在数据访问层的异常被记录日志,然后被包装在提供对调用层来说更有意义的信息的异常中。在业务组件层,异常在被传播前被记录日志。任何发生在业务组件层的包含敏感信息的异常,将被不再包含这些信息的异常所替换,这些将被发送到用户界面(UI)层,然后显示给用户。
不使用异常处理应用程序块,用于数据访问组件的典型异常处理代码看起来像如下示例。
注意:代码不包括 RunQuery、 FormatException 和 Logging.Log 方法的实现。这些访问表示了获取 DataSet 并记录日志信息的典型方式。
C#
DataSet customersDataSet;
try
{
customersDataSet = RunQuery("GetAllCustomers");
}
catch(Exception ex)
{
string formattedInfo = FormatException(ex);
Logging.Log(formattedInfo);
throw new DataAccessException("Database access failure for query GetAllCustomers",e);
}
Visual Basic
Dim customersDataSet As DataSet
Try
customerDataSet = RunQuery("GetAllCustomers")
Catch ex As Exception
Dim formattedInfo As String = FormatException(ex)
Logger.Log(formattedInfo)
Throw New DataAccessException("Database access failure for query GetAllCustomers",e)
End Try
代码类似于这将在所有完成不同数据访问查询的方法中重复。要改变异常处理代码的行为,就必须更新包含此代码的每个方法。
换句话说,使用异常处理应用程序块,同样的应用程序将有下面的代码。
注意:代码不包括 RunQuery 方法的实现。此方法表示了获取 DataSet 和记录日志信息的典型方式。
C#
DataSet customersDataSet;
try
{
customersDataSet = RunQuery("GetAllCustomers");
}
catch(Exception ex)
{
bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
if (rethrow)
throw;
}
Visual Basic
Dim customersDataSet As DataSet
Try
customerDataSet = RunQuery("GetAllCustomers")
Catch ex As Exception
Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "Data Access Policy")
If (rethrow) Then
Throw
End If
End Try
异常处理代码的行为决定于名为 Data Access Policy 的异常处理策略。应用程序将有用于 Data Access Policy 的配置设置,以指明传递到用于异常处理应用程序块的日志异常处理的类型为 System.Exception 的异常。要修改异常处理代码的行为,只需要修改配置信息即可,而不需要更新应用程序的源代码。
异 常处理应用程序块是异常处理恢复代码的补充,它没有代替恢复代码。如果因为非常不常见的原因发生异常,它会无法温和的恢复应用程序,并且结束启动它的工作 单元。然而,有时是可以恢复的。一个例子是,一个异常的发生是因为文件被锁定,恢复代码可以指示应用程序在等待一段时间后重试文件。在这种情况中,异常处 理的恢复代码将在应用程序内部实现,它不能被实现为被异常处理应用程序块所使用的处理程序。这是因为它要求访问局部变量、参数和其他的环境数据。这些数据 在由异常处理应用程序块运行的处理程序作用域之外并且无法访问。