Map Domain Objects using Automapper

Rajnilari2015
Posted by in C# category on for Beginner level | Points: 250 | Views : 4086 red flag
Rating: 4 out of 5  
 1 vote(s)

AutoMapper is a library that helps to map/transfer the data of one object (which is the source) to another object (destination object).In this article , we will look into the usage of Automapper with various examples


 Download source code for Map Domain Objects using Automapper

Introduction

AutoMapper is a library that helps to map/transfer the data of one object (which is the source) to another object (destination object).In this article , we will look into the usage of Auto-mapper with various examples

Using the code

Let us open a Console Application and then from the Nu-get Package Manager Console install auto-mapper as under

PM> Install-Package AutoMapper

Now, let us create two class say Source and Destination as under

public class Source
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAdress { get; set; }
    public string PhoneNumber { get; set; }
}

public class Destination
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAdress { get; set; }
    public string PhoneNumber { get; set; }

    public override string ToString()
    {
        return $"{Id}: {FirstName} {LastName} - {EmailAdress} - {PhoneNumber}";
    }
}

Scenario 1 : Map scalar data

In this case first we will populate a scalar record to the Source and will move that to the Destination object as under

using AutoMapper;
using GenFu;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {

            #region scalar record
            var sourceData = A.ListOf<Source>(1)[0]; //get a single record

            //Create a map
            Mapper.CreateMap<Source, Destination>();

            //use the map to move the data from source to destination
            Destination data = Mapper.Map<Source, Destination>(sourceData);

            DisplayRecord(data);

            #endregion

            Console.ReadKey();
           
        }

        private static void DisplayRecord(Destination data)
        {
            Console.WriteLine(data.ToString());
        }        
    }
}

The Mapper.CreateMap creates a mapping configuration from the TSource type to the TDestination type.Once done, then by using Mapper.Map we have executed the mapping from the source object to a new destination object. And finally, we have overridden the ToString() method of the base class (which is object) from the Destination class

.

The output is

63: Claire White - Olivia.Timms@hotmail.com - (504) 688-9340

Scenario 2 : Map collection

In this case we will move a collection of records as under

using AutoMapper;
using GenFu;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        { 

            #region Map Collection

            var sourceData = A.ListOf<Source>(10); //fill 10 records;

            //Create a map
            Mapper.CreateMap<Source, Destination>();

            //use the map to move the data from source to destination
            var data = Mapper.Map<List<Source>, List<Destination>>(sourceData);

            DisplayRecord(data);

            Console.ReadKey();

            #endregion

        }

        private static void DisplayRecord(List<Destination> data)
        {
            Enumerable.Range(0, data.Count).ToList().ForEach(i=>Console.WriteLine(data[i].ToString()));
        }
             
    }
   
}

The output is

41: Paige Mc Vicar - Keith.Russell@gmx.com - (238) 504-1866
43: Audrey Rodriguez - Miguel.Washington@microsoft.com - (398) 472-7063
90: Eric Green - Angie.Ward@gmx.com - (444) 537-3352
41: Faith Hughes - Isabella.Martin@microsoft.com - (483) 444-8475
16: Mariah Nelson - Kimberly.Long@telus.net - (533) 443-0016
9: Kaitlyn Williams - Mackenzie.Rivera@shaw.ca - (428) 602-7296
34: Robert Simmons - Shelby.Peterson@hotmail.com - (542) 720-3602
16: Mackenzie Butler - Kevin.Adams@gmx.com - (376) 621-4848
97: Briana Bell - Angelina.Williams@telus.net - (504) 209-8015
33: Angela Iginla - Erin.Hernandez@telus.net - (763) 608-3557

Scenario 3 : Map to different property name

Let us modify our Destination class as under

public class Destination
{
    public int Id { get; set; }    
    public string FullName { get; set; }
    public string EmailAdress { get; set; }
    public string PhoneNumber { get; set; }

    public override string ToString()
    {
        return $"{Id}: {FullName} - {EmailAdress} - {PhoneNumber}";
    }
}

As can be seen that, we have indroduced a property call FullName which will be a combination of FirstName and LastName.This needs to be mapped as under

using AutoMapper;
using GenFu;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {

            #region Map scalar record
            var sourceData = A.ListOf<Source>(1)[0]; //get a single record

            //Create a map
            Mapper.CreateMap<Source, Destination>();

            Mapper.CreateMap<Source, Destination>().

                ForMember(f => f.FullName, f => f.MapFrom(a => string.Concat(a.FirstName, " ", a.LastName)));

            //use the map to move the data from source to destination
            Destination data = Mapper.Map<Source, Destination>(sourceData);

            DisplayRecord(data);

            #endregion

            Console.ReadKey();
           

        }        

        private static void DisplayRecord(Destination data)
        {
            Console.WriteLine(data.ToString());
        }
    }

}

The ForMember is use for customizing configuration for individual member. The MapFrom specifies the source member to map from.

The output is

86: Hailey Yarobi - Marcus.Gomes@rogers.ca - (610) 743-9509

Scenario 4 : Map properties within properties

Let's consider the below class

public class SourceEmployee
{
    public int EmployeeID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }        
    public ResidentialAddress EmployeeResidences { get; set; }
}

public class DestinationEmployee
{
    public int EmployeeID { get; set; }
    public string FullName { get; set; }
    public ResidentialAddress EmployeeResidences { get; set; }

    public override string ToString()
    {
        return $"{EmployeeID}: {FullName} {EmployeeResidences}";
    }
}

public class ResidentialAddress
{
    public string State { get; set; }
    public string City { get; set; }
    public int ZipCode { get; set; }

    public override string ToString()
    {
        return $"{State} {City} {ZipCode}";
    }
}

Here we have EmployeeResidences property of type ResidentialAddress as a member of both the SourceEmployee and DestinationEmployee.

Now let us populate the SourceEmployee and map as under

using AutoMapper;
using GenFu;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication5
{
 class Program
 {
	    static void Main(string[] args)
	    {

	       
	        var sourceData = new SourceEmployee { EmployeeID=1, FirstName = "Niladri", LastName = "Biswas", EmployeeResidences = new ResidentialAddress { State = "Karnataka", City = "Bangalore", ZipCode=560043 } };

	        //Create a map
	        Mapper.CreateMap<SourceEmployee, DestinationEmployee>();

	        Mapper.CreateMap<SourceEmployee, DestinationEmployee>().

	            ForMember(f => f.FullName, f => f.MapFrom(a => string.Concat(a.FirstName, " ", a.LastName)));

	        //use the map to move the data from source to destination
	        DestinationEmployee data = Mapper.Map<SourceEmployee, DestinationEmployee>(sourceData);

	        DisplayRecord(data);

	        Console.ReadKey();           

	    }

	    private static void DisplayRecord(DestinationEmployee data)
	    {
	        Console.WriteLine(data.ToString());
	    }
	}
}

Here, we mapped the EmployeeResidences property of type ResidentialAddress as a member of both the SourceEmployee and DestinationEmployee. The output is as under

1: Niladri Biswas Karnataka Bangalore 560043

Scenario 5 : Map properties within properties with different property names

Let's consider the below class

public class SourceEmployee
{
    public int EmployeeID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<SourceResidentialAddress> SourceEmployeeResidences { get; set; }
}

public class SourceResidentialAddress
{
    public string State { get; set; }
    public string City { get; set; }
    public int ZipCode { get; set; }
}

public class DestinationEmployee
{
    public int EmployeeID { get; set; }
    public string FullName { get; set; }       
    public List<DestinationResidentialAddress> DestinationEmployeeResidences { get; set; }

    public override string ToString()
    {
        return $"{EmployeeID}: {FullName}";
    }
}

public class DestinationResidentialAddress
{
    public string FullAddress { get; set; }

    public override string ToString()
    {
        return $"{FullAddress}";
    }
} 

Here we will map the SourceResidentialAddress which has the properties of State,City,ZipCode to the DestinationResidentialAddress which has the property of FullAddress which is ultimately a combination of State + City + ZipCode.

Also at the same time we will map FirstName and LastName to FullName. The below is the way to do so

using AutoMapper;
using GenFu;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            //prepare the data
            var employeeRecords = A.ListOf<SourceEmployee>(2); //fill two employee records
            var employeeAddressess = A.ListOf<SourceResidentialAddress>(4); //fill 4 addresses

            Enumerable
                .Range(0, 2)
                .ToList()
                .ForEach
                    (i =>
                    {
                        switch (i)
                        {
                            case 0:
                                employeeRecords[i].SourceEmployeeResidences = employeeAddressess.Take(2).ToList(); //pick up the first 2 addresses                               
                                break;
                            case 1:
                                employeeRecords[i].SourceEmployeeResidences = employeeAddressess.Skip(2).Take(2).ToList(); //pick up the last 2 addresses                               
                                break;
                        }
                    }
                    );


            //Create a map
            Mapper.CreateMap<SourceEmployee, DestinationEmployee>();           

            Mapper.CreateMap<SourceEmployee, DestinationEmployee>()
            .ForMember(f => f.FullName, f => f.MapFrom(a => string.Concat(a.FirstName, " ", a.LastName)))
            .ForMember(x => x.DestinationEmployeeResidences, x => x.MapFrom(y => y.SourceEmployeeResidences));

            Mapper.CreateMap<SourceResidentialAddress, DestinationResidentialAddress>()
                .ForMember(x => x.FullAddress, map => map.MapFrom(from => string.Format("{0} {1} {2}", from.State, from.City, from.ZipCode)));

            List<DestinationEmployee> mappedRecords = Mapper.Map<List<SourceEmployee>, List<DestinationEmployee>>(employeeRecords);

            DisplayRecord(mappedRecords);           

            Console.ReadKey();           

        }

        private static void DisplayRecord(List<DestinationEmployee> records)
        {
            foreach(var rec in records)
            {
                Console.WriteLine(rec.ToString());
                foreach(var address in rec.DestinationEmployeeResidences)
                {
                    Console.WriteLine(address);
                }

                Console.WriteLine("-----------------------------------------------");
            }           
        }       
    }

    public class SourceEmployee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<SourceResidentialAddress> SourceEmployeeResidences { get; set; }
    }

    public class SourceResidentialAddress
    {
        public string State { get; set; }
        public string City { get; set; }
        public int ZipCode { get; set; }
    }

    public class DestinationEmployee
    {
        public int EmployeeID { get; set; }
        public string FullName { get; set; }       
        public List<DestinationResidentialAddress> DestinationEmployeeResidences { get; set; }

        public override string ToString()
        {
            return $"{EmployeeID}: {FullName}";
        }
    }

    public class DestinationResidentialAddress
    {
        public string FullAddress { get; set; }

        public override string ToString()
        {
            return $"{FullAddress}";
        }
    }
}

The output is

22: Melissa Murphy
Oregon Little Rock 40
Tennessee Tenaha 54
-----------------------------------------------
91: Melissa Patterson
Indiana Virden 25
Oregon Melita 3
-----------------------------------------------

N.B.~ The random data was generated by using GenFu

Conclusion

Hope this will be helpful.Thanks for reading. Zipped file attached.

Page copy protected against web site content infringement by Copyscape

About the Author

Rajnilari2015
Full Name: Niladri Biswas (RNA Team)
Member Level: Platinum
Member Status: Member,Microsoft_MVP,MVP
Member Since: 3/17/2015 2:41:06 AM
Country: India
-- Thanks & Regards, RNA Team


Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)