2011-09-28 33 views
5

在我的服务外观层中,我有一个服务类,其中包含一个接受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实现,从而使依赖关系解耦。

您可以提供哪些建议?

回答

4

我已经读过DDD(埃文斯)以及尼尔森的“蓝皮书”,我不清楚我应该采用什么方法进行验证。

蓝皮书从不同的角度处理该问题。我认为“验证”一词不被使用,因为它是一个危险的overgeneralization。更好的方法是考虑对象不变量,而不是验证。对象(不仅在DDD中)应该自己执行它们的内部不变量。它不是UI或服务或合同或映射器或“验证框架”或对象外部的任何其他内容。不变量在内部执行。您可能会发现这些答案有帮助:1234

我也可以把守卫在属性设置器,以防止从不断把实体为无效 状态 不可接受的值。这意味着AutoMapper在尝试映射 无效值时会失败。

您可能不应该在乎AutoMapper失败或使用AutoMapper。域对象应封装并执行其内部不变量,并在尝试破坏它时引发异常。这是非常简单的,你不应该因为某些基础设施问题而损害域对象的简单性和表现力。 DDD的目标不是满足AutoMapper或任何其他框架的要求。如果框架不适用于您的域对象,请不要使用它。

+0

链接很棒。现在很明显,允许对象进入无效状态并提供错误列表(例如,通过IDataErrorInfo)的交互式验证属于UI /表示层(ViewModel)。而且我很擅长将守卫放入我的域对象中,以防止它们进入无效状态。但是你是否主张将检查放入服务和/或外观层,除非它们跨越多个实体/聚合体? – SonOfPirate

+1

您可以根据需要将其他检查放入服务和UI中。我的观点是域对象不应该依赖这些检查。 – Dmitry

+0

@SonOfPirate - 出于利益考虑,我使用CodeContracts在我的域对象中执行不变量。 – RobertMS

1

你有两种类型的验证:

  1. 对象的一致性:是实体的责任。实体不应该允许您将它们设置为无效状态,应该强制实施相关性,值应该在范围内。你必须设计类的方法和属性以及构造函数不允许无效状态。

  2. 业务角色验证:这种验证类型需要服务器处理,如检查ID可用性,电子邮件唯一性等。这些类型的验证应在服务器中作为验证器或规格在持久性之前处理。

+3

我提供了第三个:UI验证。这旨在为用户提供交互式反馈。我认为这是更多的验证框架(如数据注释和企业库)的目标,而不是实现其他两种类型。 – SonOfPirate

+1

是的你是对的,我只专注于领域层的验证,在UI中也有验证,在视图模型或演示模型中使用任何UI兼容的验证框架来处理 –

+0

我同意你必须有自我验证域。你是否在域对象中注入了一些验证器以进行复杂(业务规则)验证? 并且您是否在命令(DTO)的应用程序层中具有基本验证? – danfromisrael