How To Integrate AutoMapper In ASP.NET Core Web API

In this article, we are going to see how to integrate AutoMapper in ASP.NET Core Web API. First, we will see what the heck is AutoMapper and which problem it solves. After that, we will integrate it with Web API and then we will take a look at commonly used features of AutoMapper. So let’s grab a cup of coffee and start learning.
 

What is AutoMapper?

 
AutoMapper is a component that helps to copy data from one type of object to another type of object. It is more like an object-object mapper. According to the AutoMapper docs,
 
AutoMapper is an object-object mapper. Object-object mapping works by transforming an input object of one type into an output object of a different type. What makes AutoMapper interesting is that it provides some interesting conventions to take the dirty work out of figuring out how to map type A to type B. As long as type B follows AutoMapper’s established convention, almost zero configuration is needed to map two types.
 

Why do we need to use AutoMapper?

 
When we have to map two different objects we can use AutoMapper. One of the problems is, while building the application we have some entities which are dealing with DB (forex DTO’s) and for some entities we are dealing with a client. So we have to map those DTO’s to the entities dealing with clients. For example, we have to two classes Student and StudentDTO as below,
 
Student
  1. public class Student  
  2. {  
  3.    public string Name {getset;}  
  4.    public int Age {getset;}  
  5.    public string City {getset;}  
  6. }  
StudentDTO
  1. public class StudentDTO  
  2. {  
  3.    public string Name {getset;}  
  4.    public int Age {getset;}  
  5.    public string City {getset;}  
  6. }  
Now we have to map those objects. Then what we create a method that can take input StudentDTO class object and map the values and return Student class object.
  1. public Student MapObjects(StudentDTO studto)  
  2. {  
  3.    return new Student() {  
  4.      name = stud.Name,  
  5.      age = stud.Age,  
  6.      city = stud.City  
  7.    };  
  8. }   
It will solve the problem but then what happens when a class has so many properties, so in that case, it is very difficult to write mappings for each and every property. And this is for one class, now if you have such 100 classes then we should have to write the same kind mapping for 100 class. So there is a simple solution to solve this problem and it is using Automapper. Let's see how we can integrate it with .NetCore Web API.
 

How AutoMapper works?

 
AutoMapper internally uses a great concept of programming called Reflection. Reflection in C# is used to retrieve metadata on types at runtime. With the help of Reflection, we can dynamically get a type of existing object and invoke its methods or access its fields and properties. You can read more about Reflection here.
 

Integrating AutoMapper in .Net Core Web API project

 
Prerequisites
  • Visual Studio 19(if you are using .Net Core 3.1)
  • .Net Core SDK installed
First thing is to create a new ASP.NET Core Web API project or you can open any existing Web API project. For those who are new to ASP.NET Core I have listed down the steps to create a new Web API project.
 
Open Visual Studio and click on File -> New -> Project. Then select ASP.NET Core Web Application and click on the Next button.
 
How To Integrate AutoMapper In ASP.NET Core Web API
 
Give the project name and click on the Create button.
 
How To Integrate AutoMapper In ASP.NET Core Web API
 
After that select API and click on Create button.
 
How To Integrate AutoMapper In ASP.NET Core Web API
So now your ASP.NET Core Web API project is setup.
 

Install AutoMapper Nuget Package

 
Right-click on the project and click on Manage Nuget Packages and search for below package,
 
How To Integrate AutoMapper In ASP.NET Core Web API
 
Or open Package Manager Console and run below command
  1. Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection  
The above package will automatically install the AutoMapper package for us since it references the same package.
 

Configure AutoMapper

 
Now we have installed the AutoMapper package. So the next step is to configure for our ASP.NET Core Web API Open the Startup.cs class and add the below code into ConfigureServices method.
  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.     services.AddControllers();  
  4.     services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());  
  5. }  
The AddAutoMapper method provided by the AutoMapper package which traverse the assembly and checks for the class which inherits from the Profile class of AutoMapper. This method takes a single assembly or list of assemblies as input. We have used AppDomain.CurrentDomain.GetAssemblies() which gives an array of assemblies in this application domain.
 

Creating classes

 
So to make thing simple create two classes called Student.cs and StudentDTO.cs
  1. namespace automapper_sample  
  2. {  
  3.     public class Student  
  4.     {  
  5.         public string Name { getset; }  
  6.         public int Age { getset; }  
  7.         public string City { getset; }  
  8.     }  
  9. }  
  1. namespace automapper_sample  
  2. {  
  3.     public class StudentDTO  
  4.     {  
  5.         public string Name { getset; }  
  6.         public int Age { getset; }  
  7.         public string City { getset; }  
  8.     }  
  9.  

Creating Profiles

 
Create a new class called AutoMapperProfile.cs which inherits from Profile class of AutoMapper. Use CreateMap<source, destination>() to create a mapping between classes.
  1. using AutoMapper;  
  2.   
  3. namespace automapper_sample  
  4. {  
  5.     public class AutoMapperProfile : Profile  
  6.     {  
  7.         public AutoMapperProfile()  
  8.         {  
  9.             CreateMap<StudentDTO, Student>();  
  10.         }  
  11.     }  
  12. }  
So here we have mapped StudentDTO to Student class.
 
When the application starts it will initialize AutoMapper and then AutoMapper scans all assemblies & look for classes that inherit from the Profile class and load their mapping configurations. It’s really simple.
 

Using IMapper

 
IMapper interface is used to map two objects. Create a new controller called StudentController.cs. Resolve the IMapper dependency in the controller constructor.
  1. using AutoMapper;  
  2. using Microsoft.AspNetCore.Mvc;  
  3.   
  4. namespace automapper_sample.Controllers  
  5. {  
  6.     [Route("api/[controller]")]  
  7.     public class StudentController : Controller  
  8.     {  
  9.         private readonly IMapper _mapper;  
  10.   
  11.         public StudentController(IMapper mapper)  
  12.         {  
  13.             _mapper = mapper;  
  14.         }  
  15.   
  16.         // GET: api/<controller>  
  17.         [HttpGet]  
  18.         public Student Get()  
  19.         {  
  20.             StudentDTO studentDTO = new StudentDTO()  
  21.             {  
  22.                 Name = "Student 1",  
  23.                 Age = 25,  
  24.                 City = "New York"  
  25.             };  
  26.   
  27.             return _mapper.Map<Student>(studentDTO);  
  28.         }  
  29.     }  
  30. }  
We have created a new object of StudentDTO class and assign values to it. So now we have to map it with Student class, we used _mapper.Map() method. Do you wonder from where the IMapper is injected? We haven't registered it in ServiceCollection. AddAutoMapper() method in your ConfigureServices takes care of all of this for you.
Now start the API and browse /api/student to see the result.
 
How To Integrate AutoMapper In ASP.NET Core Web API
That’s it. You have successfully configured AutoMapper into your Web API project.
 

Commonly used features of AutoMapper

 
In this section, we will be looking at some of the commonly used features of AutoMapper.
 

Projection

 
Now you must be thinking about what happens when source class has a different property name than the destination class. Let’s do it & see the output. So for demo purpose, I have changed the StudentDTO City property to CurrentCity as below: 
  1. namespace automapper_sample  
  2. {  
  3.     public class StudentDTO  
  4.     {  
  5.         public string Name { getset; }  
  6.         public int Age { getset; }  
  7.         public string CurrentCity { getset; }  
  8.     }  
  9. }  
And I haven’t changed Student class which looks like as below:
  1. namespace automapper_sample  
  2. {  
  3.     public class Student  
  4.     {  
  5.         public string Name { getset; }  
  6.         public int Age { getset; }  
  7.         public string City { getset; }  
  8.     }  
  9. }  
So now after running the application, you will see the City is not mapped with CurrentCity property,
 
How To Integrate AutoMapper In ASP.NET Core Web API
To solve this problem we have concepts in AutoMapper called Projection. So to solve this we have to define a mapping for all the property which are different in both classes.
 
Open the AutoMapperProfile.cs file and add below code,
  1. namespace automapper_sample  
  2. {  
  3.     public class AutoMapperProfile : Profile  
  4.     {  
  5.         public AutoMapperProfile()  
  6.         {  
  7.             CreateMap<StudentDTO, Student>()  
  8.                 .ForMember(dest => dest.City, opt => opt.MapFrom(src => src.CurrentCity));  
  9.         }  
  10.     }  
  11. }  
Now run the application and see the output,
 
How To Integrate AutoMapper In ASP.NET Core Web API

Nested Mappings

 
In the previous feature, we have seen that how to map two different properties but now think what happens when both classes have Inner class with it. For example, suppose StudentDTO has a property which is of type AddressDTO class and Student class has nested class property called Address.
  1. namespace automapper_sample  
  2. {  
  3.     public class AddressDTO  
  4.     {  
  5.         public string State { getset; }  
  6.         public string Country { getset; }  
  7.     }  
  8. }  
  1. namespace automapper_sample  
  2. {  
  3.     public class StudentDTO  
  4.     {  
  5.         public string Name { getset; }  
  6.         public int Age { getset; }  
  7.         public string CurrentCity { getset; }  
  8.         public AddressDTO Address { getset; }  
  9.     }  
  10. }  
  1. namespace automapper_sample  
  2. {  
  3.     public class Address  
  4.     {  
  5.         public string State { getset; }  
  6.         public string Country { getset; }  
  7.     }  
  8. }  
  1. namespace automapper_sample  
  2. {  
  3.     public class Student  
  4.     {  
  5.         public string Name { getset; }  
  6.         public int Age { getset; }  
  7.         public string City { getset; }  
  8.         public Address Address { getset; }  
  9.     }  
  10. }  
So to map these Nested classes we have to write mapping for nested classes also in our AutoMapperProfile.cs class
  1. using AutoMapper;  
  2.   
  3. namespace automapper_sample  
  4. {  
  5.     public class AutoMapperProfile : Profile  
  6.     {  
  7.         public AutoMapperProfile()  
  8.         {  
  9.             CreateMap<StudentDTO, Student>()  
  10.                 .ForMember(dest => dest.City, opt => opt.MapFrom(src => src.CurrentCity));  
  11.             CreateMap<AddressDTO, Address>();  
  12.         }  
  13.     }  
  14. }  
The output looks like,
 
How To Integrate AutoMapper In ASP.NET Core Web API 

Conditional Mappings

 
Most of the times we have to map property on the basis of some conditions. And to do this AutoMapper has a concept called Conditional Mappings. While writing mappings we can specify conditions for the specific properties.
  1. using AutoMapper;  
  2.   
  3. namespace automapper_sample  
  4. {  
  5.     public class AutoMapperProfile : Profile  
  6.     {  
  7.         public AutoMapperProfile()  
  8.         {  
  9.             CreateMap<StudentDTO, Student>()  
  10.                 .ForMember(dest => dest.City, opt => opt.MapFrom(src => src.CurrentCity))  
  11.                 .ForMember(dest => dest.IsAdult, opt => opt.MapFrom(src => src.Age > 18 ? true : false));  
  12.             CreateMap<AddressDTO, Address>();  
  13.         }  
  14.     }  
  15. }  
So in the above example, you can see that IsAdult property is calculated based on condition i.e Age > 18.
 
AutoMapper provides so many other features to simplify complex mappings. You can check docs here.
 

Conclusion

 
In this article, I have explained about AutoMapper and how to integrate it with ASP.NET Core Web API. I also demonstrated some of the commonly used features of AutoMapper.I really hope that you enjoyed this article, and please do not hesitate to send me your thoughts or comments about what could I have done better.
Happy Coding!