我有一个MVC2 n-tier应用程序(DAL,Domain,Service,MVC web),采用DDD方法(领域驱动设计),具有带有仓储的领域模型。我的服务层使用请求/响应模式,其中请求和响应对象包含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; }
}
我考虑过三种不同的方式来建模响应对象。
选项1 - 最符合DRY原则的选项:
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; }
}
这样可以让代码更加DRY(避免重复),可重用和易于管理,并且不会将我的域结构暴露给最终用户。另一个主要优点是,其他响应,例如GetCompanyResponse
可以简单地返回CompanyDTO
,而无需复制所有那些属性,类似于选项2。你认为呢?你采取了哪个选项(如果有的话)并且是否适用于你?如果这些请求/响应后来作为WCF服务方法公开,您的答案会改变吗?