域对象到ViewModel &反之亦然,使用Automapper

本文关键字:使用 Automapper 反之亦然 对象 ViewModel | 更新日期: 2023-09-27 17:51:07

我正在为我的公司开发一个新的MVC站点&有点困惑,如何创建映射从域/POCO对象到ViewModel类[包含验证]&亦然。下面是一个示例。

我的域类[为了保持简单,我省略了其他属性]:

public partial class Glossary
{
    public int Id { get; set; }
    public string GlossaryItem { get; set; }
    public string Definition { get; set; }
}

我的ViewModel类在我的MVC应用程序的模型文件夹[与相应的验证]:

public class GlossaryModel
{
    [HiddenInput(DisplayValue = false)]
    public int Id { get; set; }
    [Required(ErrorMessage = "Please enter a GlossaryItem")]
    public string GlossaryItem { get; set; }
    [Required(ErrorMessage = "Please enter a Definition")]
    public string Definition { get; set; }
}

my Automapper configuration for DTO to Domain Model:

protected override void Configure()
{
     CreateMap<GlossaryModel, Glossary>();
     //....... etc
}

我的控制器编辑项的动作方法:

public class GlossaryController : Controller
{
    IGlossaryRepository _glossaryRepository;
    IMappingService _mappingService;
    public GlossaryController(IGlossaryRepository glossaryRepository, IMappingService autoMapperMappingService)
    {
        _glossaryRepository = glossaryRepository;
        _mappingService = autoMapperMappingService;
    }
    // .... etc
    [HttpPost, ValidateAntiForgeryToken]
    public virtual ActionResult Edit(GlossaryModel glossaryModel)
    {
        if (ModelState.IsValid)
        {
            var glossary = _mappingService.Map<GlossaryModel, Glossary>(glossaryModel);
            if (glossaryModel.Id <= 0)
                _glossaryRepository.Add(glossary);
            else
                _glossaryRepository.Edit(glossary);
            _glossaryRepository.Save();
            TempData["message"] = string.Format("{0} has been saved", glossaryModel.Definition);
            return RedirectToAction("All");
        }
        return View(glossaryModel);
    }
    //....etc
 }

它工作得很好,但我的问题是…现在假设我需要一个动作来列出所有的词汇表项,比如…

public ActionResult All()
{
    var allItems = _glossaryRepository.Glossary;
    if (allItems.Count() == 0) return View(new List<GlossaryModel>());
    // **The below line is the reverse mapping one**
    var allItemsModel = _mappingService.Map<IEnumerable<Glossary>, IEnumerable<GlossaryModel>>(allItems);
    return View(allItemsModel);
}

但是现在我需要automapper从Domain对象转换为DTO[从List(Glossary)到List(GlossaryModel)],正好与Edit方法相反,将数据推送到视图。所以我需要再次在automapper配置中映射相反的绑定吗? !!像

protected override void Configure()
{
     CreateMap<GlossaryModel, Glossary>(); // Added before for DTO to Domain object 
     CreateMap<Glossary, GlossaryModel>();// Added for Domain object to DTO
     //....... etc
}

双向绑定是一个好的设计吗?或者有更好的解决方案,我错过了,请帮助

谢谢,桑杰

域对象到ViewModel &反之亦然,使用Automapper

Jimmy Bogard也问了同样的问题。但有足够的需求,直接支持已经添加到简单的情况下,如你所列出的。事实上,在这个回答中,Jimmy还表示,如果它对你有效,那就没有错。一个简单的例子是:

protected override void Configure()
{
    CreateMap<GlossaryModel, Glossary>()
        .ReverseMap();
    //....... etc
}

注意ReverseMap不适用于更复杂的映射。

Automapper被构建为域到视图模型(域到DTO的方式,你已经描述过了)映射

@Marius的回答总结得很好,双向映射有什么错?

在一些中等规模的项目中,我使用了双向映射,对于较大的项目,我使用域到视图模型映射,然后使用CQRS系统将ViewModel值发送到底层持久性存储。

归根结底,这取决于您如何选择使用Automapper,以及哪些架构决策对您有意义。

世界不会停止旋转,如果你做双向映射