C# 是否通过 AutoMapper 将域模型映射到视图模型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16527921/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 01:13:58  来源:igfitidea点击:

Mapping domain model to view model via AutoMapper or not

c#asp.net-mvc-4automapper

提问by Pingpong

I want to use view model for display insted of domain model. And I want to customise a property for display, how should I do this? And is it a good practice to use AutoMapper for display?

我想使用视图模型来显示域模型的插入。我想自定义一个显示属性,我应该怎么做?使用 AutoMapper 进行显示是一个好习惯吗?

Below is the code sample:

下面是代码示例:

public class BookController : BaseController
    {
        private IBookService bookService;

        public BookController(IBookService bookService)
        {
            this.bookService = bookService;
        }

        public ActionResult Details(int id)
        {
            var book = bookService.GetBookById(id);

            return View(Mapper.Map<BookView>(book));
        }
}

    public class Book 
    {        
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
    }

    public class BookView
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

If I use another way, I can customise any property, like below:

如果我使用另一种方式,我可以自定义任何属性,如下所示:

  public ActionResult Details(int id)
        {
            var book = bookService.GetBookById(id);

            return View(new BookView(book));
        }

    public class BookView
    {
       public BookView(Book book){
         Name = book.Name +" Decorated";
       }
        public int Id { get; set; }
        public string Name { get; set; }
    }

How should I do this? And is it a good practice to use AutoMapper for display?

我该怎么做?使用 AutoMapper 进行显示是一个好习惯吗?

Update

更新

It seems using automapper in the scenario below is more appropriate. For example, mapping a view model to domain model like below. Any opinions?

在下面的场景中使用 automapper 似乎更合适。例如,将视图模型映射到域模型,如下所示。有什么意见吗?

  [HttpPost]
    public ActionResult Create(BookView bookView)
    {
        try
        {
            var book = Mapper.Map<Book>(bookView);  //this is wrong

            bookService.SaveOrUpdate(book);

            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

Update 2

更新 2

For complex custom display via view model, I don't want to use automapper to map display logic, assuming automapper can map it. Because it mixes different purposes. For example:

对于通过视图模型的复杂自定义显示,我不想使用 automapper 来映射显示逻辑,假设 automapper 可以映射它。因为它混合了不同的目的。例如:

Mapper.CreateMap<Book, BookView>()
    .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name + " this is for display purpose"));

However, using manual mapping like below seems intuitive.

但是,使用如下所示的手动映射似乎很直观。

 public BookView(Book book){
    //mapping here
}

Update 3

更新 3

Quote from Jimmy Bogard:

引用Jimmy Bogard 的话

I think using AutoMapper because you don't want to use the “=” operator is a bit lazy. Instead, we use it to flatten and reshape, optimizing for the destination type's environment. Remember, my original motivation for AutoMapper was:

Enable protecting the domain layer from other layers by mapping to DTOs

我认为使用 AutoMapper 因为您不想使用“=”运算符有点懒惰。相反,我们使用它来展平和重塑,优化目的地类型的环境。请记住,我对 AutoMapper 的最初动机是:

通过映射到 DTO 来保护域层免受其他层的影响

Thanks @AndrewWhitaker for the link

感谢@AndrewWhitaker 提供链接

采纳答案by Andrew Whitaker

This is a good use case for AutoMapper (I've used it this way extensively on many projects with success). Generally you do notwant to expose domain entities to your view (in MVC, this would be exposing your model directly to your view, which is incorrect).

这是 AutoMapper 的一个很好的用例(我已经在许多成功的项目中以这种方式广泛使用它)。一般你希望暴露领域实体到您的视图(MVC中,这将直接暴露你的模型,以你的观点,这是不正确的)。

You do not need a 1-1 mapping between domain entity and viewmodel. You can make them look completely different and customize the mapping in your CreateMap<>call. To use your example:

您不需要域实体和视图模型之间的 1-1 映射。您可以让它们看起来完全不同,并在您的CreateMap<>通话中自定义映射。使用您的示例:

Mapper.CreateMap<Book, BookView>()
    .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name + " Decorated"));

Worst case, you can ditch automapper for complex cases or use a custom type resolver with automapper to get the job done.

最坏的情况是,您可以在复杂情况下放弃 automapper,或者使用带有 automapper 的自定义类型解析器来完成工作。

In fact, this is how Jimmy Bogard (the author) recommends using AutoMapper. He specifically mentions mapping from domain entities to ASP.NET MVC ViewModels for use with strongly typed views.

事实上这就是 Jimmy Bogard(作者)推荐使用 AutoMapper 的方式。他特别提到了从域实体到 ASP.NET MVC ViewModel 的映射,以便与强类型视图一起使用。

Another advantage is that you can unit test your mapping profiles. This way if you end up with a mismatch between ViewModel and Model you'll get a failing unit test.

另一个优点是您可以对映射配置文件进行单元测试。这样,如果您最终发现 ViewModel 和 Model 之间不匹配,您将获得失败的单元测试。

Updates:

更新:

I think the quote you added to your question further supports using AutoMapper for mapping from domain models to ViewModels:

我认为您在问题中添加的引用进一步支持使用 AutoMapper 将域模型映射到 ViewModel:

Instead, we use it to flatten and reshape, optimizing for the destination type's environment.

相反,我们使用它来展平和重塑,优化目的地类型的环境。

So in my example you'd definitely be optimizing for the destination type's environment(in this case a view).

因此,在我的示例中,您肯定会针对目标类型的环境(在本例中为视图)进行优化

Also per the link I reference above you should notbe using automapper to map tothe domain, only from. With that in mind, you'll have to write some logic to create/update domain entities from what you receive from the View no matter what. Remember that controller actions should not take domain entities directly (you should not trust data that comes directly from the view--let the model determine if a domain entity would be valid or not).

同样根据我上面引用的链接,您应该使用 automapper 映射域,只能. 考虑到这一点,无论如何,您都必须编写一些逻辑来根据从 View 收到的内容创建/更新域实体。请记住,控制器操作不应直接采用域实体(您不应信任直接来自视图的数据——让模型确定域实体是否有效)。