自从 Microsoft 推出应用程序 block 以来,我一直遇到使用 Exception Handling Application Block 的人。 。我最近自己仔细研究了一下,并将基本功能总结如下(如果您已经知道它的作用,请跳过以下 block ):
The exception handling application block aims to centralize and make fully configurable with config files the following key exception handling tasks:
- Logging an Exception
- Replacing an Exception
- Wrapping an Exception
- Propagating an Exception
- etc.
The library does that by having you modify your try catch blocks as follows:
try { // Run code. } catch(DataAccessException ex) { bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy"); if (rethrow) { throw; } }
Based on what is specified in the app.config for the policy name (see here for docs), HandleException will either ...
- throw a completely new exception (replace the original exception)
- wrap the original exception in a new one and throw that
- swallow the exception (i.e. do nothing)
- have you rethrow the original exception
Additionally you can also configure it to do more stuff beforehand (e.g. log the exception).
现在我的问题是:我完全不明白无论异常是被替换、包装、吞没还是重新抛出,使其可配置有什么好处。根据我的经验,必须在编写代码时做出此决定,因为当您更改异常处理行为时,通常必须更改周围或调用代码。
例如,当您重新配置时,您的代码可能会开始表现不正确,以便在特定点引发的特定异常现在被吞噬而不是重新引发(catch block 后面可能有一些代码,当异常发生时不得执行)发生)。这同样适用于异常处理中所有其他可能的更改(例如替换 -> 重新抛出、吞下 -> 包装)。
所以,对我来说最重要的是异常处理 block 解决了实际中不存在的问题。异常日志记录和通知位很好,但所有其他东西不都是过度设计的完美示例吗?
最佳答案
如果您使用异常来控制流,那么您会希望远离基于策略的异常处理。
但是,如果您希望将异常视为不可恢复(后台任务失败、套接字断开连接、文件被删除等),您可能需要可配置的、基于策略的异常处理.
例如,如果您正在开发 API,您可能希望 API 中的每个函数仅抛出标准异常(ArgumentException
等)以及您自己的库特定异常内部非标准异常(例如 MyLibraryException
)的情况下的异常。在这种情况下,重要的是某些东西无法正常工作。您并没有分解异常并找出问题所在。您只是承认某些事情出了问题,并且您现在应该做某些事情。
某些东西应该是可配置的,因为你做什么并不重要。向用户显示消息框?模态还是非模态?记录异常?您想如何记录异常?调用日志 Web 服务?附加到日志文件?写入 Windows 事件日志?在数据库中插入一个条目?将条目插入两个数据库?这对你的应用程序的其余部分并不重要。如何处理异常的选择与应用程序的其余部分完全正交。
(顺便说一句,这不是我处理可配置的基于策略的异常处理的方式。我更倾向于 AOP 风格,例如在容器中注册异常记录器拦截器。)
关于.net - Microsoft 异常处理 block - 这不是过度设计的完美示例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/408480/