对象映射器与对象包装器
Object mapper vs Object wrapper
如果能给我一点帮助,我将不胜感激...
假设在一个应用程序中我们有一个数据层和一个业务逻辑层。在 DAL 中,我们有以下实体:
public class Customer {
public string Name {get; set;}
public ICollection<Address> Addresses {get; set;}
}
public class Address {
public string Street {get; set;}
}
在 BLL 中,我们有以下 POCO:
public class CustomerDto {
public string Name {get; set;}
public ICollection<AddressDto> Addresses {get; set;}
}
public class AddressDto {
public string Street {get; set;}
}
DAL 中的实体使用轻量级 ORM 填充,并使用存储库从 BLL 中检索。例如:
public class CustomerInformationService {
private readonly ICustomerRepository _repository {get; set;}
public CustomerInformationService (ICustomerRepository repository)
{
_repository = repository;
}
public class CustomerDto Get(int id)
{
var customerEntity = _repository.Get(id);
var customerDto = /* SOME TRANSFORMATION HERE */
return customerDTO;
}
}
我的问题是关于 /* SOME TRANSFORMATION HERE */ 部分。我们的团队正在讨论如何执行 "mapping"。
一种方法是使用自动映射器或手动映射器。
第二种方法是使用类似于 Entity 的包装器并引用 DTO 以保存对象之间的复制操作。像这样:
public class CustomerDto
{
private IEntity _customerEntity;
public IEntity CustomerEntity { get {return _customerEntity;}}
public CustomerDto(IEntity customerEntity)
{
_customerEntity = customerEntity;
}
public string Name
{
get { return _customerEntity.Name; }
}
public ICollection<Address> Addresses
{
get { return _customerEntity.Addresses; }
}
}
我觉得第二种方法有点奇怪,因为 _customerEntity.Addresses 感觉像是我的 DAL 和 BLL 之间的泄漏(_customerEntity 的参考),但我不确定。
有没有advantages/disavantages使用一种方法而不是另一种方法?
附加信息:我们通常拉一个最大值。一次需要在实体和 DTO 之间转换的 1000 条记录。
我打赌服务层方法。基本上是因为看起来像业务对象或 域对象 的东西与 DTOs.
无关
而且,事实上,您和您的团队应该使用 AutoMapper 而不是多次重复相同的代码,这包括将一些属性从 A 设置到 B,从 A 到 C , C 到 B...
您没有提到您的“ligth-weight ORM”。我分两部分回答。
如果您使用的是创建代理的 ORM
您应该避免将实体暴露在特定边界之外。像 NHibernate/EF 这样的 ORM 实现了基于代理的延迟加载。如果您将实体暴露给 application/UI 层,您将无法控制 ORM 行为。这可能会导致很多意想不到的问题,调试起来也会很困难。
在 DTO 中包装实体将一无所获。无论如何,您正在访问实体。
使用 DTO 并使用 AutoMapper 等映射器工具映射它们是很好的解决方案。
如果您使用的是不创建代理的 ORM
不要使用 DTO,直接使用您的实体。在许多情况下,DTO 在此处很有用并推荐使用。但是你给出的例子根本不需要DTO。
如果您选择使用 DTO,将实体包装在 DTO 中是没有意义的。如果无论如何都要使用 Entity,为什么要包装它?同样,像 AutoMapper 这样的工具可以提供帮助。
参考this问题。有点不同;我在问 Yes/No 而你在问 How。但它仍然会帮助你。
如果能给我一点帮助,我将不胜感激...
假设在一个应用程序中我们有一个数据层和一个业务逻辑层。在 DAL 中,我们有以下实体:
public class Customer {
public string Name {get; set;}
public ICollection<Address> Addresses {get; set;}
}
public class Address {
public string Street {get; set;}
}
在 BLL 中,我们有以下 POCO:
public class CustomerDto {
public string Name {get; set;}
public ICollection<AddressDto> Addresses {get; set;}
}
public class AddressDto {
public string Street {get; set;}
}
DAL 中的实体使用轻量级 ORM 填充,并使用存储库从 BLL 中检索。例如:
public class CustomerInformationService {
private readonly ICustomerRepository _repository {get; set;}
public CustomerInformationService (ICustomerRepository repository)
{
_repository = repository;
}
public class CustomerDto Get(int id)
{
var customerEntity = _repository.Get(id);
var customerDto = /* SOME TRANSFORMATION HERE */
return customerDTO;
}
}
我的问题是关于 /* SOME TRANSFORMATION HERE */ 部分。我们的团队正在讨论如何执行 "mapping"。
一种方法是使用自动映射器或手动映射器。 第二种方法是使用类似于 Entity 的包装器并引用 DTO 以保存对象之间的复制操作。像这样:
public class CustomerDto
{
private IEntity _customerEntity;
public IEntity CustomerEntity { get {return _customerEntity;}}
public CustomerDto(IEntity customerEntity)
{
_customerEntity = customerEntity;
}
public string Name
{
get { return _customerEntity.Name; }
}
public ICollection<Address> Addresses
{
get { return _customerEntity.Addresses; }
}
}
我觉得第二种方法有点奇怪,因为 _customerEntity.Addresses 感觉像是我的 DAL 和 BLL 之间的泄漏(_customerEntity 的参考),但我不确定。
有没有advantages/disavantages使用一种方法而不是另一种方法?
附加信息:我们通常拉一个最大值。一次需要在实体和 DTO 之间转换的 1000 条记录。
我打赌服务层方法。基本上是因为看起来像业务对象或 域对象 的东西与 DTOs.
无关而且,事实上,您和您的团队应该使用 AutoMapper 而不是多次重复相同的代码,这包括将一些属性从 A 设置到 B,从 A 到 C , C 到 B...
您没有提到您的“ligth-weight ORM”。我分两部分回答。
如果您使用的是创建代理的 ORM
您应该避免将实体暴露在特定边界之外。像 NHibernate/EF 这样的 ORM 实现了基于代理的延迟加载。如果您将实体暴露给 application/UI 层,您将无法控制 ORM 行为。这可能会导致很多意想不到的问题,调试起来也会很困难。
在 DTO 中包装实体将一无所获。无论如何,您正在访问实体。
使用 DTO 并使用 AutoMapper 等映射器工具映射它们是很好的解决方案。
如果您使用的是不创建代理的 ORM
不要使用 DTO,直接使用您的实体。在许多情况下,DTO 在此处很有用并推荐使用。但是你给出的例子根本不需要DTO。
如果您选择使用 DTO,将实体包装在 DTO 中是没有意义的。如果无论如何都要使用 Entity,为什么要包装它?同样,像 AutoMapper 这样的工具可以提供帮助。
参考this问题。有点不同;我在问 Yes/No 而你在问 How。但它仍然会帮助你。