简体   繁体   中英

Domain object to ViewModel & vice versa using Automapper

I'm developing a new MVC site for my company & kind of confused as how to create mapping from Domain/POCO objects to ViewModel classes [contains validation] & vice versa. Here's an sample example.

My domain class [just to keep it simple I'hv omitted other properties]:

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

my ViewModel class inside my MVC app's model folder [with corrosponding validation]:

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
}

My controller's action method for editing an item:

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
 }

And it's working fine, but my question is... Now say I need an action that will list down all glossary items like..

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

But now I need automapper to convert from Domain objects to DTO [from List(Glossary) to List(GlossaryModel)], just opposite of the Edit method, to push the data to the view. So do I again need to map the opposite binding in the automapper config...!! like

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

Is it a good design to bind both ways? or there's better solution I'm missing, Please help

Thanks, Sanjay

Jimmy Bogard also asked the same question . But there was enough demand for it that direct support has been added for simple cases like you've listed. In fact, in this answer Jimmy also suggested that there's nothing wrong with it if it works for you. A simple example is:

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

Note that ReverseMap doesn't work for more complex mappings. See this answer for more details.

Automapper was build to Domain to ViewModel (Domain to DTO in the manner in which you've described it) mapping

Summed up well by @Marius' answer here What is wrong with two-way mapping?

In some medium sized projects I've used two way mapping and for larger projects I use Domain To View Model mapping and then used a CQRS system for sending the ViewModel values to the underlying persistence store.

When it comes down to it, it is up to you how you choose to use Automapper and what Architectural decisions make sense to you.

The world will not stop rotating if you do 2 way mapping.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM