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

时间:2013-01-09 06:03:17

标签: c# asp.net-mvc-4 automapper

我正在为我的公司开发一个新的MVC网站&有点混淆如何创建从Domain / POCO对象到ViewModel类的映射[包含验证]&反之亦然。这是一个示例。

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

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

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

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; }
}

我的DTO到域模型的Automapper配置:

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
}

绑定两种方式是一个好的设计吗?还是我错过了更好的解决方案,请帮助

谢谢, 桑杰

2 个答案:

答案 0 :(得分:2)

Jimmy Bogard也问了same question。但是有足够的需求,直接支持has been added用于您列出的简单案例。事实上,在this answer中,吉米也暗示如果它适合你,那就没有错。一个简单的例子是:

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

请注意,ReverseMap不适用于更复杂的映射。有关详细信息,请参阅this answer

答案 1 :(得分:1)

Automapper构建到Domain to ViewModel(以您描述的方式进行DTO的域)映射

总结@Marius在这里回答What is wrong with two-way mapping?

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

当涉及到它时,由您决定如何选择使用Automapper以及您认为哪些架构决策有意义。

如果你进行双向映射,世界将不会停止旋转。