Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • How to use Automapper in .NET ?

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 237
    Comment on it

    Hi Friends,

    Before knowing about "How to use Automapper" we should know what mapping is and then we'll see how to make it "automatic". So I am taking here an ASP.NET MVC example to make things easier and understandable.

    By name mapping we can understand that some property of one model is going to by mapped with another one and the Automapper makes that automatic but we'll see a real life scenario of mapping . Take the simplest example in MVC. We're going to show user details on a view.

    Consider the Following code snippet in controller:

    var dbContext = new MyDataContext();
     var details = dbContext.Users.FirstOrDefault(userId => userId.UserId == id); 
    var user = new AutoMapperExample.Models.User(); 
    if ( details != null)
     { 
      user.UserId = details .UserId;
      user.EMail = details .EMail; 
      user.FirstName = details .FirstName; 
      user.LastName = details .LastName; 
      user.Address = details .Address; 
     } 
    return View(user);

    This is an easy code. I accept that it is not very well structured but for understanding the mapping and automapping ,it'll do. So here we're doing following things.

    1-Getting an object of "User" type from database in "details" variable.

    2-And mapping the properties of "details" to the properties of "User" object inside if block.

    So step 2 is good when we've 4 or 5 properties but when we've more than 10 or 15, writing and mapping all of them is tedious and confusing to some extent.

    So here comes the Automapper. If I say that those two things up there can be mapped automatically,that'll sound like a relief from that confusion and tedious coding, isn't it?

    Automapper is a third party tool which takes classes and maps them to each other. To install that you just need to run following command :

    PM>  Install-Package AutoMapper

    When the Automapper is added to your project, we can replace all of the code of mapping with following code:

    AutoMapperExample.Models.User user = 
                  Mapper.Map<AutoMapperExample.User, AutoMapperExample.Models.User>(users);
                

    So the above code snippet becomes:

     Mapper.CreateMap<AutoMapperExample.User, AutoMapperExample.Models.User>();
    var dbContext = new MyDataContext();
     var details = dbContext.Users.FirstOrDefault(userId => userId.UserId == id); 
    var user = new AutoMapperExample.Models.User(); 
    if ( details != null)
     { 
      AutoMapperExample.Models.User userDetail = 
                  Mapper.Map<AutoMapperExample.User, AutoMapperExample.Models.User>(user);
     } 
    return View(userDetail);

    Now we can see that what is "auto" here. So let's take a look at the changed syntax a bit:

    Mapper.CreateMap<AutoMapperExample.User,AutoMapperExample .Models.User>();

    Here we're calling the "CreateMap" method and defining the types to be mapped:

    • AutoMapperExample .User -> DTO Object Class(Data Transfer Objects-objects having data from database)
    • AutoMapperExample .Models.User->Model class to bind the view 

    Now we call the "Map()" method to get the Mapped object of the " AutoMapperExample .Models.User" which takes the object of  AutoMapperExample.User(DTO Object class) object as parameter:

    AutoMapperExample.Models.User userDetail =
                  Mapper.Map<AutoMapperExample.User, AutoMapperExample.Models.User>(user);

    This is one scenario where we can use the Automapper and this is pretty straightforward. What may be the other scenario. There may be a scenario where we have an Employee class with following properties:

    public class Employee
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public Address Address { get; set; }
        public string Position { get; set; }
        public bool Gender { get; set; }
        
    }

    and one Address Class as following:

    public class Address
    {
        public string City { get; set; }
        public string Street { get; set; }
        public int Number { get; set; }            
    }

    Now we want to show these details to some Gridview or Repeater kind of control , be it in web or desktop. You can take it as simple HTML table too. Everything is fine until you have to show address as single string and gender as "Male" or "Female".

    So we create a new class say EmployeeViewModel as following:

    public class EmployeeViewModel
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public string Address { get; set; }
        public string Position { get; set; }
        public string Gender { get; set; }
    }

    But the problem is that the Address property in the Address class is of complex type. So how are we going to show complete address? Moreover we don't have any idea to show "Male" and "Female" as string as these are coming as "bool" in Employee class.

    So here we can do following things using AutoMapper:

    For Address

    Mapper.CreateMap<Employee, EmployeeViewModel>()
    .ForMember(ev => ev.Address, 
        m => m.MapFrom(a => a.Address.City + ", " + 
                       a.Address.Street + " " + 
                       a.Address.Number))
    .ForMember(/*next member to map with formatting*/);

    In the above code snippet  the "CreateMap()" method is same as before but there is a "ForMember()" method which takes two parameters.

    1-In which property you have to Map-in this case EmployeeViewModel(ev).Address

    2-MapFrom -From where you have to map-Employee Model.Address.City /Street/Number

    So by using this we've just created complete address or string type from our complex type in Employee Model.

    Now we move to the Gender part.

    For Gender

    Here in Gender we need to have a method which returns the Gender in string after getting input gender type as bool. So I am having some assumptions  here:

    1-We're taking true or false for gender in Employee Model.

    2- We're getting "true" as gender in Employee Model.

    3-We're taking a console application example for easy demonstration of things.

    So following is the class which returns "Male" or "Female" :

    public class GenderResolver : ValueResolver<bool, string>
        {
            protected override string ResolveCore(bool source)
            {
                return source ? "Male" : "Female";
            }
        }

    Our GenderResolver class derives from ValueResolver class and Overrides it's "ResolveCore" Method. These are the classes and methods available in Automapper Dll(except GenderResolver- It is a custom class and you are free to name it as per you wish) so if you're not getting any of this, just copy paste the whole block. It's not that tough by the way:-).

    Now we'll use our GenderResolver class for resolving the gender to a string value and map it to EmployeeViewModel Gender which is of string type. Remember the commented section of ".ForMember()" method in the address part?

    Write following code snippet in there:

    ev => ev.Gender, m => m.ResolveUsing<GenderResolver>().FromMember(e => e.Gender)

    Here this "ResolveUsing()" method takes the class type as our class "GenderResolver" and returns "Male" as string.

    So we've configured the mapping part, we've one last "Map()" method to write. So write following code snippet:

    EmployeeViewModel employeeVIew Model  = Mapper.Map<Employee, EmployeeViewModel>(employee); 

    Here the "employee" parameter is what you are getting from database and which contains the "Gender" as "True".

    This is how the whole code looks like:

    namespace AutoMapperExample      
    {
        public class Employee
        {
            public string Name { get; set; }
            public string Email { get; set; }
            public Address Address { get; set; }
            public string Position { get; set; }
            public bool Gender { get; set; }
        }
    
        public class Address
        {
            public string City { get; set; }
            public string Street { get; set; }
            public int Number { get; set; }
        }
    
        public class EmployeeViewModel
        {
            public string Name { get; set; }
            public string Email { get; set; }
            public string Address { get; set; }
            public string Position { get; set; }
            public string Gender { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Mapper.CreateMap<Employee, EmployeeViewModel>()
                   .For(ev => ev.Address, m => m.MapFrom(a => a.Address.City + ", " + a.Address.Street + " " + a.Address.Number))
                   .ForMember(ev => ev.Gender, m => m.ResolveUsing<GenderResolver>().FromMember(e => e.Gender));
                   
    //Here you can get the values and fill the Employee Model from db.
                Employee employee = new Employee
                {
                    Name = "XYZ",
                    Email = "ABC@xyz.com",
                    Address = new Address
                    {
                        
                        City = "Dehradun",
                        Street = "XYZ Street",
                        Number = 5
                    },
                    Position = "Developer",
                    Gender = true
                    
                };
                //Now map the Employee View Model
                EmployeeViewModel employeeViewModel = Mapper.Map<Employee, EmployeeViewModel>(employee);            
            }        
    
            public class GenderResolver : ValueResolver<bool, string>
            {
                protected override string ResolveCore(bool source)
                {
                    return source ? "Male" : "Female";
                }
            }
    
            
        }
    }

    So we've seen the practical usage scenario of AutoMapper in above examples. Apart from ValueResolvers there are other classes like "ValueFormatters" to format dates etc. Feel free to use them and please ask any questions in the comments section.

    Thank You.

    Happy Coding:-).

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: