5

我正在使用 DDD 模式开发类似企业的项目。我的 C# 解决方案中有以下项目:

  • 领域模型 - DLL 项目

  • WebUI - ASP.NET MVC3 项目

  • DesktopUI - WPF 项目

  • DAL - 实体框架代码优先

  • 持久性 - SQL Server 数据库

这个项目并不大,但我正在尝试使用企业应用程序的所有良好实践。

我现在想定义的是异常策略,但我不确定如何处理。我可能应该使用企业库异常处理和日志记录块,但我不确定如何将其融入图片中。我试图在脑海中解决的一些具体场景如下:

  • 如果用户在 WPF 应用程序中创建了新实体,并且单击了“保存”按钮,应如何报告和记录错误以防不同级别发生异常(例如,实体未根据域规则正确创建,或者存在尝试将新对象持久保存到数据库时出错)

  • 用户尝试从数据库中检索未知实体(例如,通过在 URL 中指定未知实体 ID 从 WebUI)

我知道我可以定义自定义异常,但我不太确定在哪里以及如何。是否应该为每一层定义它们?我知道有包装异常的做法,但又不太确定如何最好地使用该模式。

我还应该为某个层中的每个错误创建一个自定义异常(例如,UserAlreadyExistInDatabaseException 用于尝试使用相同的电子邮件保存两个用户,以及 UnknownUserDatabaseException 如果尝试从 DB 获取未知用户),还是应该使用一种异常类型来处理多个层错误(例如 DatabaseException,然后用自定义属性或 Exception.Message 属性区分错误)。

4

1 回答 1

7

我会远离 EntLib 异常处理和日志记录块,因为它们太复杂而无法配置和处理。您当然可以探索它们以了解如何解决这些类型的问题,但通常更容易推出自己的解决方案或使用 log4net 或 NLog 之类的东西进行日志记录。

就处理异常而言,表示层(WPF 或 ASP.NET)应捕获并解释应用程序服务层引发的异常。应用程序服务封装了您的领域,包括领域模型和数据访问层(DDD 中的存储库)。应用程序服务可以返回包含错误信息的结果对象,也可以从域或 DAL 传播异常。

如果您打算捕获它们以便对给定的异常类型执行特定的操作,则应该创建自定义异常类型。诸如此类的异常UserAlreadyExistInDatabaseException可能会有所帮助,因为应用程序服务可以捕获它并返回某种结果对象以由表示层解释,或者可以在表示层中捕获异常,然后通知用户。

日志记录可以在应用程序服务层或表示层或两者兼而有之。例如,应用程序服务可以从 DAL 捕获异常,记录它,并将其包装在表示层可以解释的另一个异常中。

用户尝试从数据库中检索未知实体

这可以通过多种方式处理。一种方法是应用服务返回一个空引用,表示层返回一个适当的消息给用户。或者,DAL 可以引发类似 EntityNotFoundException 的内容,可以在表示层捕获,同时向用户返回适当的消息。引发这样的异常对于 ASP.NET MVC 之类的东西可能是有益的,因为您可以创建一个操作过滤器,该过滤器在接收到所述类型的异常时返回通用响应。

于 2012-06-26T00:28:05.727 回答