传统错误处理倾向于遵循所有函数根据成功/失败返回代码的方法.您将检查此代码并正确处理(如果出现错误).
然而,现代编程语言遵循异常模型,如果发生无法正常处理的异常事件,则抛出异常 - 这会一直冒泡直到处理完毕.
我的问题是为什么我们走向异常模式?这背后的原因是什么?为什么更好?
非常感谢解释/链接.
在我的服务外观层,我有一个服务类,其方法/操作接受DTO(数据契约)对象.AutoMapper用于将此DTO映射到我的域对象的实例以应用任何更改.请求将传递到我的域服务,该服务执行实际工作.这是方法的样子:
public EntityContract AddEntity(EntityContract requestContract)
{
var entity = Mapper.Map<EntityContract, Entity>(requestContract);
var updatedEntity = Service.AddEntity(entity);
var responseContract = Mapper.Map<Entity, EntityContract>(updatedEntity);
return responseContract;
}
Run Code Online (Sandbox Code Playgroud)
使用构造函数注入和Unity作为IoC容器来设置Service和Mapper属性.
在执行操作时,域服务对实体进行更改,然后使用存储库来保存更改,如:
public Entity AddEntity(Entity entity)
{
// Make changes to entity
Repository.Add(entity);
// Prepare return value
}
Run Code Online (Sandbox Code Playgroud)
还使用构造函数注入设置存储库.
问题是,一旦数据被持久化,数据立即可供其他客户端使用,因此我必须确保不会保留无效数据.我已经阅读了DDD(埃文斯)和尼尔森的"蓝皮书",我不清楚我应该采取什么样的验证方法.
如果我的目标是阻止实体进入无效状态,我应该在服务方法中验证entityContract以确保在将请求传递给我的域服务之前满足所有规则吗?我不愿意这样做,因为我似乎打破了在服务外观中定义这些规则的封装.
我们使用薄外观层委托给域服务的原因是我们在API中暴露了粗粒度的接口,但是通过细粒度域服务的组合支持重用.请记住,多个Facade服务可能正在调用相同的域服务方法,也许将这些规则委托给域服务会更好,因此我们知道每个用法都经过验证.或者我应该在两个地方验证?
我还可以在属性设置器中放置防护装置,防止不可接受的值将实体置于无效状态.这意味着AutoMapper在尝试映射无效值时会失败.但是,当没有映射值时,它没有帮助.
我仍然无法理解这些规则是实体行为的一部分,并且确定对象是否有效应该封装在实体中.这是错的吗?
首先,我需要确定执行这些验证检查的时间和地点.然后我需要弄清楚如何用DI实现,以便依赖关系解耦.
你能提供什么建议?
我一直在研究使用服务层来验证我的域模型,然后再将它们保存到数据库中.
我找到了以下使用扩展方法来验证我的模型的例子,但是想知道这样做是否有任何特定的缺点?我没有看到提到的验证(除了数据注释).
我正在考虑实施以下内容:
public class FooService : IFooService {
public bool Add(Foo foo) {
if (!foo.IsValid()) {
return false
}
try ... catch
}
}
Run Code Online (Sandbox Code Playgroud)
public static class validationExtensions {
public static bool IsValid(this Foo foo) {
// Call my validation implementation here
}
}
Run Code Online (Sandbox Code Playgroud)
我很紧张,因为我没有看到这个建议/实施太多.思考?