在我的服务外观层中,我有一个服务类,其方法/操作接受 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;
}
Service 和 Mapper 属性是使用 Unity 作为 IoC 容器的构造函数注入来设置的。
在执行操作时,域服务对实体进行更改,然后使用存储库来保存更改,例如:
public Entity AddEntity(Entity entity)
{
// Make changes to entity
Repository.Add(entity);
// Prepare return value
}
存储库也是使用构造函数注入来设置的。
问题是,数据一旦被持久化,就立即可供其他客户端使用,因此我必须确保不会持久化任何无效数据。我读过 DDD (Evans) 和 Nilsson 的“蓝皮书”,但不清楚我应该采取什么方法进行验证。
如果我的目标是防止实体进入无效状态,我是否应该在服务方法中验证entityContract,以确保在将请求传递到域服务之前满足所有规则?我犹豫是否要这样做,因为在服务外观中定义这些规则似乎破坏了封装。
我们使用薄的外观层委托给域服务的原因是,我们在 API 中公开了粗粒度的接口,但通过细粒度的域服务的组合来支持重用。请记住,多个外观服务可能会调用相同的域服务方法,也许将这些规则委托给域服务会更好,这样我们就知道每次使用都经过验证。或者我应该在两个地方验证?
我还可以在属性设置器中放置防护装置,以防止不可接受的值将实体置于无效状态。这意味着 AutoMapper 在尝试映射无效值时会失败。但是,当没有映射任何值时,它没有帮助。
我仍然无法摆脱这样的想法:这些规则是实体行为的一部分,并且确定对象是否有效应该封装在实体内。这是错误的吗?
因此,首先我需要确定何时何地执行这些验证检查。然后我需要弄清楚如何使用 DI 来实现,以便解耦依赖关系。
您能提供什么建议?