我有一个使用DDD方法(域驱动设计)的MVC2 n层应用程序(DAL,域,服务,MVC Web),具有带存储库的域模型。我的服务层使用请求/响应模式,其中Request和Response对象包含DTO(数据传输对象)以将数据从一个层封送到下一个层,并且映射通过AutoMapper的帮助完成。我的问题是: DTO通常采用什么样的形状?它是否可以嵌套/复杂 DTO,或者它应该严格地是平面投影? 或者可能是两者的混合?此外,使用平面DTO与更复杂/嵌套DTO的主要原因是什么?
例如,假设我有一个域名,如下所示:
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Company Company { get; set; }
}
public class Company
{
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
}
我想到了三种不同的方法来建模Response对象。
选项1 - DRYest选项:
public class GetEmployeeResponse
{
public class EmployeeDTO { get; set; } // contains a CompanyDTO property
}
根据我所做的研究,如上所示,DTO采用与域对象类似的形状是不合适的。
选项2 - 域名的平面投影(反DRY):
public class GetEmployeeResponse
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string CompanyName { get; set; }
public string CompanyAddress { get; set; }
public string CompanyCity { get; set; }
public string CompanyState { get; set; }
}
这更简单,就像DTO显然应该这样,但最终会产生更多的DTO。
选项3 - 两者的混合:
public class GetEmployeeResponse
{
public EmployeeDTO Employee { get; set; }
public CompanyDTO Company { get; set; }
}
这允许代码更干燥,可重用和可管理,并且不会将我的域结构暴露给最终用户。另一个主要好处是其他响应,例如GetCompanyResponse
可以简单地返回CompanyDTO
,而不必复制所有这些属性,类似于选项2.您如何看待?您有哪些选择(如果有的话)和/或为您工作过?如果这些请求/响应稍后作为WCF服务方法公开,您的答案是否会改变?
答案 0 :(得分:11)
我个人的偏好是尝试尽可能保持平坦,只传输所需的数据。说过去我曾经使用过深度嵌套的DTO,因为它在当时有意义且符合要求。所以我猜它归结为“它取决于”。在一天结束时,请考虑手头的应用程序。没有必要尝试将喇叭数据转换为不符合您要达到的目标的DTO惯例。