asp.net-mvcmodel-view-controllerautomapperobject-object-mapping

Is it good practice to use object-to-object mappers? If so, when should I use one?


I’ve done some searching and read a few articles about object-to-object mappers, but none of them really gave me a clear answer. Is it generally a good idea to use an object mapper to map one object to another?

I understand that it depends on the situation, but how can I tell when using an object mapper is the right or best approach?


Solution

  • Taking a step back, it's best practice to separate data transfer objects (DTOs) and view models (VMs) from business objects (entities and alike). Mapping libraries, in that regard, are a means to an end and simply make that association easier.

    As far as when, that's up to you. If you feel like you can convert between your business models and DTO/VMs in a way that's easy to maintain, go ahead. From my personal experience, that only goes so far (especially as the requirements change). Therefore, I'm fond of mapping libraries (specifically AutoMapper as I've come to know it's API and am comfortable plugging it in).

    Having said that, any time I have to go between these two models I use AutoMapper. I simply configure it once and I'm off and running. Additional tweaks to the models (on either side) then become easier as I can change those bindings in one place (map definition file) and methods automatically "catch up".


    Example:

    My database contains a Record for a product:

    class Product
    {
        public int Id { get; set; }
    
        public string Description { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
        public int QuantityOnHand { get; set; }
        public int? ReorderQuantity { get; set; }
        public string Sku { get; set; }
    }
    

    I may present this to the UI in a more distilled format:

    public class ProductViewModel
    {
        public int Id { get; set; }
    
        public string Description { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
        public int Quantity { get; set; }
    }
    

    If this came from a repository of some kind, I'm simply calling:

    var model = Mapper.Map<ProductViewModel>(productFromRepository)
    

    Here I consistently get the view model I care about from the Product I've requested. If the business/service layer were to add/change/remove properties, I'd only go back to my Mapper.CreateMap<Product, ProductViewModel>() defintion, but the rest of my presentation logic would remain in-tact.