How to use profiles, reverse mapping, nested mapping, and other advanced operations of the open source object mapper AutoMapper Credit: Thinkstock AutoMapper is a convention-based, object-oriented mapper. An object-oriented mapper is one that transforms an input object into an output object of a different type. AutoMapper also can be used to map similar or dissimilar objects (i.e., objects having properties that may or may not be identical). We examined the basic features of AutoMapper in a previous article. In this article we’ll explore some of the advanced features of AutoMapper. Create an ASP.Net Core project in Visual Studio First off, let’s create a new ASP.Net Core project in Visual Studio. Note that you can create any project, i.e., MVC or even a Console Application, to work with AutoMapper. If Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new ASP.Net Core project. Launch the Visual Studio IDE. Click on “Create new project.” In the “Create new project” window, select “ASP.Net Core Web Application” from the list of templates displayed. Click Next. In the “Configure your new project” window shown next, specify the name and location for the new project. Click Create. In the “Create New ASP.Net Core Web Application” window shown next, select .Net Core as the runtime and ASP.Net Core 2.2 (or later) from the drop-down menu at the top. Select “Web Application” as the project template to create a new ASP.Net Core web application. Ensure that the check boxes “Enable Docker Support” and “Configure for HTTPS” are unchecked as we won’t be using those features here. Ensure that Authentication is set to “No Authentication” as we won’t be using authentication either. Click Create. Now you should have a new ASP.Net Core project ready to go in Visual Studio. We’ll use this project in the subsequent sections of this article to illustrate a few advanced operations using AutoMapper. Install AutoMapper To start working with AutoMapper, you should install the necessary packages in your project. To do this, you can use the following commands at the NuGet Package Manager Console window: Install-Package AutoMapper Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection Assuming the installation is successful, you are all set to use AutoMapper in your project. Configure AutoMapper Once AutoMapper has been successfully installed, you can configure it by calling the AddAutoMapper method on the IServiceCollection instance. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion (CompatibilityVersion.Version_2_2); services.AddAutoMapper(); } Use profiles to specify mapping information in AutoMapper You can organize your mapping collections using profiles. To create a profile, you need to create a class that extends the Profile class of the AutoMapper library. You can then add the necessary mapping configuration information to the constructor of the class you just created. The CreateMap method is used to create mapping between two types. The following class shows how you can create a class named AuthorProfile by extending the Profile class and specifying mapping information. public class AuthorProfile : Profile { public AuthorProfile() { CreateMap<AuthorModel, AuthorDTO>(); } } Use the ReverseMap() method in AutoMapper Note that the example above is a one-way mapping. Similarly, suppose you have defined a one-way mapping using the CreateMap method as shown in the code snippet below. AutoMapper.Mapper.CreateMap<Author, AuthorModel>(); You can now map an instance of the Author class to an AuthorModel as shown below. var authorModel = AutoMapper.Mapper.Map<AuthorModel>(author); Now suppose you would like to map the AuthorModel instance back to an Author instance. You might try using the following code. var author = AutoMapper.Mapper.Map<Author>(authorModel); However, note that this would throw a runtime exception. The exception occurs because the AutoMapper runtime lacks the knowledge needed to perform this mapping. One way to achieve this reverse mapping is by recreating the mapping from the scratch. A simpler and better way is by using the ReverseMap method off the CreateMap method, as shown in the code snippet below. AutoMapper.Mapper.CreateMap<Author, AuthorModel>().ReverseMap(); Use the ForMember() and MapFrom() methods in AutoMapper This next example will use the AuthorModel and AuthorDTO classes from my previous article on AutoMapper. You can refer to that article here. The following code snippet illustrates how you can map objects of the AuthorModel and AuthorDTO classes. var author = new AuthorModel(); author.Id = 1; author.FirstName = "Joydip"; author.LastName = "Kanjilal"; author.Address = "Hyderabad"; var authorDTO = _mapper.Map<AuthorDTO>(author); Now suppose the property named Address has been changed to Address1 in the AuthorModel class. public class AuthorModel { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Address1 { get; set; } } You can then update the mapping information in the AuthorProfile class as shown below. public class AuthorProfile : Profile { public AuthorProfile() { CreateMap<AuthorModel, AuthorDTO>().ForMember (destination => destination.Address, map => map.MapFrom(source => source.Address1)); } } Use NullSubstitute in AutoMapper Suppose the Address field in the AuthorModel is null and you would like to have something like “No data” in lieu of a null value. Here’s where NullSubstitution comes into action. The following code snippet illustrates how it can be used to replace null values with “No data”. AutoMapper.Mapper.CreateMap<AuthorModel, AuthorDTO>() .ForMember(destination => destination.Address, opt => opt.NullSubstitute("No data")); Use before and after mapping in AutoMapper Consider the following two classes. public class OrderModel { public int Id { get; set; } public string ItemCode { get; set; } public int NumberOfItems { get; set; } } public class OrderDTO { public int Id { get; set; } public string ItemCode { get; set; } public int NumberOfItems { get; set; } } You can take advantage of the BeforeMap() method to perform some calculation or initialize a data member in the source or destination instance. The following code snippet illustrates how this can be achieved. Mapper.Initialize(cfg => { cfg.CreateMap() .BeforeMap((src, dest) => src.NumberOfItems = 0) }); The AfterMap() method can be used to execute operations on the destination object after a mapping has been done. Here’s how you can use the AfterMap() method on the destination instance. public OrderDTO MapAuthor(IMapper mapper, OrderDTO orderDTO) { return mapper.Map<OrderModel, OrderDTO>(orderDTO, opt => { opt.AfterMap((src, dest) => { dest.NumberOfItems = _orderService.GetTotalItems(src); }); }); } Use nested mapping in AutoMapper AutoMapper can be used to map nested objects as well. Consider the following domain classes. public class Order { public string OrderNumber { get; set; } public IEnumerable<OrderItem> OrderItems { get; set; } } public class OrderItem { public string ItemName { get; set; } public decimal ItemPrice { get; set; } public int ItemQuantity { get; set; } } Consider the following classes that represent data transfer objects. public class OrderDto { public string OrderNumber { get; set; } public IEnumerable<OrderItemDto> OrderItems { get; set; } } public class OrderItemDto { public string ItemName { get; set; } public decimal ItemPrice { get; set; } public int ItemQuantity { get; set; } } You can use the following code to establish a mapping. var orders = _repository.GetOrders(); Mapper.CreateMap<Order, OrderDto>(); Mapper.CreateMap<OrderItem, OrderItemDto>(); var model = Mapper.Map<IEnumerable<Order>, IEnumerable<OrderDto>>(orders); AutoMapper enables you to map objects with minimal configuration. You can even map objects having different data structures by using a custom resolver. The custom resolver can generate an exchange object that has the same structure as the destination object so that the AutoMapper runtime can map the types at runtime. Related content feature 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos