在我的服务外观层中,我有一个服务类,其中包含一个接受DTO(数据合约)对象的方法/操作。 AutoMapper用于将此DTO映射到我的域对象的实例中以应用任何更改。该请求被传递到我的域服务上,该服务执行实际的工作。这里的方法可能是什么样子:使用IoC验证SOA应用程序中的DDD
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;
}
的服务和映射属性是通过构造器注入与团结作为IoC容器集。
在执行操作时,该域的服务进行改变的实体然后使用一个存储库,以坚持像的变化:
public Entity AddEntity(Entity entity)
{
// Make changes to entity
Repository.Add(entity);
// Prepare return value
}
存储库是使用构造器注入也被设置。
的问题是,一旦它已经坚持,所以我要确保没有无效数据持久化数据变得立即提供给其他客户。我读过DDD(埃文斯)和Nilsson的“蓝皮书”,我不清楚我应该采取什么方法进行验证。
如果我的目标是防止实体进入无效状态,我应该验证entityContract在我服务的方法,以确保所有的规则都满足不断请求传递到我的域名服务之前?我毫不犹豫地这样做,因为它好像我打破封装在服务门面中定义这些规则。
我们使用薄层门面层委托给域服务的原因是我们在API中公开了粗粒度的接口,但是通过细粒度域服务的组合支持重用。请记住,多个Facade服务可能调用相同的域服务方法,可能将这些规则委托给域服务会更好,因此我们知道每个使用都经过验证。或者我应该在两个地方进行验证?
我也可以把守卫在属性设置器,以防止从不断把实体为无效状态不可接受的值。这意味着AutoMapper在尝试映射无效值时会失败。但是,当没有值映射时,它不起作用。
我仍然不能让过去的思维,这些规则是实体的行为的一部分,并确定该对象是否有效应该在实体内进行封装。这是错的吗?
所以首先我需要确定何时何地执行这些验证检查。然后我需要弄清楚如何使用DI实现,从而使依赖关系解耦。
您可以提供哪些建议?
链接很棒。现在很明显,允许对象进入无效状态并提供错误列表(例如,通过IDataErrorInfo)的交互式验证属于UI /表示层(ViewModel)。而且我很擅长将守卫放入我的域对象中,以防止它们进入无效状态。但是你是否主张将检查放入服务和/或外观层,除非它们跨越多个实体/聚合体? – SonOfPirate
您可以根据需要将其他检查放入服务和UI中。我的观点是域对象不应该依赖这些检查。 – Dmitry
@SonOfPirate - 出于利益考虑,我使用CodeContracts在我的域对象中执行不变量。 – RobertMS