我希望使用视图模型来显示,而不是领域模型。我想自定义一个属性以供显示,应该如何操作?使用AutoMapper用于显示是否是一个好的实践?
以下是代码示例:
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; }
}
如果我采用其他方式,就可以自定义任何属性,例如如下:
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; }
}
我该怎么做?使用AutoMapper在展示方面是一个好的实践吗?
更新
看起来在下面这种场景中使用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();
}
}
更新 2
对于通过视图模型进行复杂自定义显示的情况,我不想使用 AutoMapper 来映射显示逻辑,即使 AutoMapper 可以映射它。因为这样会混淆不同的目的。例如:
Mapper.CreateMap<Book, BookView>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name + " this is for display purpose"));
然而,像下面这样使用手动映射似乎很直观。
public BookView(Book book){
//mapping here
}
更新3
引用自Jimmy Bogard:
我认为只因为你不想使用 " = " 运算符就使用 AutoMapper 是有点懒。相反,我们使用它来展平和重塑,优化目标类型的环境。请记住,我创造 AutoMapper 的最初动机是:
通过映射到 DTOs 实现保护域层免受其他层的影响
感谢 @AndrewWhitaker 提供的链接
-->
DTO 创建完全不同的映射。此外,你不应该使用 AutoMapper 将任何东西映射到领域。 - Andrew Whitaker