使用AutoMapper ViewModel(DTO)到模型(实体)的最佳实践

时间:2014-08-25 07:30:02

标签: c# asp.net automapper

我很高兴在一些项目中使用AutoMapper,并在从ViewModel转到Model时使用了.ReverseMap()。我通常会做以下事情:

// run at startup
// I'd customize the mapping if needed
Mapper.CreateMap<Model, ViewModel>().ReverseMap();

[HttpPost]
public ActionResult Create(SomeModel viewModel)
{
    var data = Mapper.Map<Model>(viewModel);
    _repo.Insert(data);
    _uow.Save();
    return View();
}

然后我找到这篇文章:http://lostechies.com/jimmybogard/2009/09/18/the-case-for-two-way-mapping-in-automapper/

我很放松。

文章是否过时或是否有更好的方法?

1 个答案:

答案 0 :(得分:2)

免责声明 :有各种不同的域和架构,这个答案可能根本不适用于您的设计目标或架构。您当然可以随意使用AutoMapper。另外,我没有写这篇文章,所以我使用自己的经验来处理某些类型的项目。


域层的重要性

首先,相关文章假设您使用的是某些版本的domain driven design。至少,我认为它吸引了一个领域的想法,这个领域是项目的一个非常重要的部分,应该“受到保护”。最能总结这个想法的是:

  

...因为那时我们的映射层会影响我们的域模型。

作者不希望域层之外的工件更新域。

为什么呢?这是因为:

  • 域模型是项目的核心。
  • 对域层的修改应该是一个严肃的操作 - 域层本身处理的最重要的部分。

文章提到了允许解决方案的映射部分进行域模型更新的一些问题,包括:

  

强制可变的公共收集,例如public EntitySet<Category> Categories { get; }&lt; - NO。

您可能想知道为什么拥有一个可变的公共集合是一件坏事 - 从域模型的角度来看,您可能不希望在任何需要的时候在(可能无效的)类别中进行某些外部服务爆破。

在这种情况下,添加类别的更合理的API将是:

  • 具有AddCategoryRemoveCategory方法,实体本身在添加之前会对其进行一些验证。
  • 公开永远不会被外部消费者修改的IEnumerable<Category> { get; }

我最近工作的一个项目有一个非常复杂的领域。只有在通过多个验证服务(生活在域中)进行预期更新操作后,域实体才会更新。

如果我们允许将映射回到域实体,我们会引入一个巨大的设计问题。

允许AutoMapper(或其他映射项目)直接映射到我们的域实体将破坏域实体中的逻辑(或者更可能是执行验证的域服务)并在域层中创建一种“后门”

替代

希望上面的评论提供了一些帮助。不幸的是,当您进行自动映射时,另一种方法是使用普通的“=。但至少,如果您处于DDD环境中,您将被迫更多地考虑在创建或更新域实体之前应该发生什么。

然而

...存在.ReverseMap方法。我认为这篇文章仍适用于某种类型的项目。自动创建双向映射的内置功能意味着库能够处理目标应用程序之外的应用程序。

如免责声明中所述,双向映射可能对您的应用程序有充分的理解。