我在网上搜索了一些,找到了一些关于这个主题的文章,但没有一篇让我满意。我想知道使用对象-对象映射器将对象相互映射是好的吗?我知道这取决于使用的情况,但我如何确定一个好的或最佳的使用情况?
退一步说,将数据传输对象(dto)和视图模型(vm)与业务对象(实体等)分开是最佳实践。在这方面,映射库是达到目的的一种手段,只是使这种关联更容易。
至于什么时候,那取决于你。如果您觉得可以以易于维护的方式在业务模型和DTO/vm之间进行转换,那么请继续进行。从我个人的经验来看,这只能到此为止(特别是当需求发生变化时)。因此,我喜欢映射库(特别是AutoMapper,因为我已经知道它的API,并且可以轻松地插入它)。话虽如此,每当我必须在这两个模型之间进行选择时,我都会使用AutoMapper。我只需配置一次,就可以开始运行了。对模型(两侧)的额外调整变得更容易,因为我可以在一个地方(映射定义文件)更改这些绑定,并且方法会自动"赶上"。
的例子:
我的数据库包含一个产品的记录:
class Product
{
public int Id { get; set; }
public string Description { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public int QuantityOnHand { get; set; }
public int? ReorderQuantity { get; set; }
public string Sku { get; set; }
}
我可能会以一种更精炼的格式呈现给UI:
public class ProductViewModel
{
public int Id { get; set; }
public string Description { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public int Quantity { get; set; }
}
如果这来自某种存储库,我只是调用:
var model = Mapper.Map<ProductViewModel>(productFromRepository)
在这里,我始终从我请求的Product中获得我关心的视图模型。如果业务/服务层要添加/更改/删除属性,我只需回到我的Mapper.CreateMap<Product, ProductViewModel>()
定义,但其余的表示逻辑将保持不变。
除了@Brad Christie的回答之外,如果你想在视图中与其他以不同方式生成的产品一起显示,那么将具有微小差异的类型自动映射为单个总体类型通常更容易。
如果你允许我抄下我自己以前的一个答案,这里有一个例子:
class SingleProduct {
string Name {get;set;}
decimal Price {get;set;}
decimal GetActualPrice() { return Price; }
}
class ComboSaleProduct {
string Name {get;set;}
List<SingleProduct> ComboProducts {get;set;}
decimal GetActualPrice() { return ComboProducts.Sum(p => p.GetActualPrice()); }
}
class ProductViewModel {
string Name {get;set;}
decimal ActualPrice {get;set;}
}
Automapper将所有内容连接在一起,以便您可以返回其中任何一个,它将自动将"GetActualPrice"映射到视图模型上的ActualPrice。