我正在使用DDD模式开发类似企业的项目。我在C#解决方案中有以下项目:
域模型 - DLL项目
WebUI - ASP.NET MVC3项目
DesktopUI - WPF项目
DAL - 实体框架代码优先
持久性 - SQL Server数据库
这个项目并不大,但我试图使用企业应用程序的所有良好实践。
我现在要定义的是例外策略,但我不确定如何处理。我应该使用企业库异常处理和记录块,但我不知道如何将其纳入图片。我想在脑海中解决的一些具体情况如下:
如果用户在WPF应用程序中创建了新实体,并且单击了“保存”按钮,则如果在不同级别发生异常(例如,未根据域正确创建实体),应如何报告和记录错误规则,或尝试将新对象持久保存到数据库时出错(
用户尝试从数据库中检索未知实体(例如,通过在URL中指定未知实体ID从WebUI中检索)
我知道我可以定义自定义异常,但我不确定在哪里以及如何。它们应该按每层定义吗?我知道有包装异常练习但又不太确定如何最好地使用该模式。
我也应该为某个层中的每个错误创建一个自定义异常(例如,UserAlreadyExistInDatabaseException尝试使用相同的电子邮件保存两个用户,如果尝试从DB获取未知用户则为UnknownUserDatabaseException)或者我应该有一个处理的异常类型多层错误(例如,DatabaseException,然后使用自定义属性或Exception.Message属性区分错误)。
答案 0 :(得分:7)
我会远离EntLib异常处理和日志记录块,因为它们太复杂而无法配置和处理。您当然可以探索它们以了解如何处理这些类型的问题,但通常更容易推出自己的解决方案或使用log4net或NLog等日志记录。
就处理异常而言,表示层(WPF或ASP.NET)应该捕获并解释应用程序服务层引发的异常。应用程序服务封装了您的域,包括域模型和数据访问层(DDD中的存储库)。应用程序服务可以返回可包含错误信息的结果对象,也可以传播来自域或DAL的异常。
如果要捕获它们以便执行特定于给定异常类型的操作,则应创建自定义异常类型。诸如UserAlreadyExistInDatabaseException
之类的异常可能会有所帮助,因为应用程序服务可以捕获它并返回某种结果对象以供表示层解释,或者异常可以在表示层中捕获,从而通知用户
可以在应用程序服务层或表示层或两者上完成日志记录。例如,应用程序服务可以从DAL捕获异常,记录它,并将其包装在表示层可以解释的另一个异常中。
用户尝试从数据库中检索未知实体
这可以通过多种方式处理。一种方法是app服务返回空引用,表示层向用户返回适当的消息。或者,DAL可以引发类似EntityNotFoundException的东西,它可以在表示层捕获,也向用户返回适当的消息。提升这样的异常对于ASP.NET MVC这样的事情是有益的,因为你可以创建一个动作过滤器,它在收到所述类型的异常时返回一般响应。