Standards In Defining The AutoMappers

Introduction 

 
We all know that by using AutoMapper, we can reduce the pain of assigning values to one object from another object manually everywhere in our project. Automapper helps in auto assigning the values from one object to another object.
 
Here are three standard things to follow while defining the profiles:
  1. Never use .ForAllOtherMembers(e=>e.Ignore());
    If we use this, it will override all the members that are not mentioned in the mapping profiles. There is a risk of losing any property while getting mapped from the domain object to another object. If we don't use this in our mapping configuration, then any missed properties in the model will be known during the run time of the solution (an Invalid Configuration error will be thrown)
  2. If the property name is identical in both the objects, then there is no need to mention it explicitly in the mapper configurations.
  3. If the property name is different in both the objects, then you need to mention this property mapping in the configuration.
  4. If you don’t require any property to be not mapped, then mention the property as ignore.
Example
 
Here, I have two domain models, Customer and Country.
  1. using System;  
  2. namespace AutMapper.Models {  
  3.     public class Customer {  
  4.         public int Id {  
  5.             get;  
  6.             set;  
  7.         }  
  8.         public string Name {  
  9.             get;  
  10.             set;  
  11.         }  
  12.         public string CountryId {  
  13.             get;  
  14.             set;  
  15.         }  
  16.         public DateTime JoiningDate {  
  17.             get;  
  18.             set;  
  19.         }  
  20.         public bool PrimeUser {  
  21.             get;  
  22.             set;  
  23.         }  
  24.         public Country Country {  
  25.             get;  
  26.             set;  
  27.         }  
  28.     }  
  29. }  
  30. namespace AutMapper.Models {  
  31.     public class Country {  
  32.         public int Id {  
  33.             get;  
  34.             set;  
  35.         }  
  36.         public string Name {  
  37.             get;  
  38.             set;  
  39.         }  
  40.     }  
  41. }  
I have my dto model for customer which I will be using this model as return type of my API.
  1. using System;  
  2. namespace AutMapper.Models {  
  3.     public class CustomerDto {  
  4.         public int Id {  
  5.             get;  
  6.             set;  
  7.         }  
  8.         public string CustomerName {  
  9.             get;  
  10.             set;  
  11.         }  
  12.         public string CountryId {  
  13.             get;  
  14.             set;  
  15.         }  
  16.         public DateTime JoiningDate {  
  17.             get;  
  18.             set;  
  19.         }  
  20.         public bool PrimeUser {  
  21.             get;  
  22.             set;  
  23.         }  
  24.     }  
  25. }  
Now I need to map the data from customer model to CustomerDto model. Lets do the mapping by using the above standards.
  1. using AutoMapper;  
  2. namespace AutMapper.Models {  
  3.     public class CustomerMappingProfiles: Profile {  
  4.         public CustomerMappingProfiles() {  
  5.             CreateMap < Customer, CustomerDto > ()  
  6.                 //Both the properties are having different Names  
  7.                 .ForMember(e => e.CustomerName, src => src.MapFrom(e => e.Name))  
  8.                 //Mapping the property from another table which have relation.  
  9.                 .ForMember(e => e.Country, src => src.MapFrom(e => e.Country.Name))  
  10.                 //Ignoring the property which is not required.  
  11.                 .ForMember(e => e.Id, e => e.Ignore());  
  12.         }  
  13.     }  
  14. }  
CustomerName
 
Here, the property name is different in both the models, hence we need to mention the configuration explicitly.
 
Id
 
I don’t want the Id property in my model to be exposed. Hence, I'm using e.Ignore() to restrict the data from the domain object to my dto object.
 
Country
 
I want to get the country name from the countries domain model by using CountryId from the customer domain model. Hence, I am mapping the property using the domain model of the country.
 
Note
Always call the mapper in the Iquerable state rather than a list because the related tables data won’t be mapped in the list state.
 
Now for other properties I haven’t mapped, they will be automatically mapped as the property name is identical in both the models. Let’s suppose if you use the ForAllOtherMembers(e=>e.Ignore()); then the properties which are not mentioned above will not be mapped. For a model with 5 to 10 properties, it is easy to find, but in real scenarios we may have a model with above 20 properties, hence following these standards will help us overcome these challenges.