Reverse Mapping Using AutoMapper in C#

Reverse Mapping Using AutoMapper in C# with Examples

In this article, I am going to discuss the Reverse Mapping Using AutoMapper in C# with some examples. This is one of the most important concepts to understand in AutoMapper. The Automapper Reverse Mapping is nothing but the two-way mapping which is also called as bidirectional mapping. Please read our previous article before proceeding to this article where we discussed how to map Complex type to Primitive Type using AutoMapper in C# with examples.

As of now, the mapping we discussed are one directional means if we have two types let’s say Type A and Type B, then we Map Type A with Type B. But using Automapper Reverse mapping it is also possible to Map Type B with Type A.

Let us understand Reverse Mapping Using AutoMapper in C# with an example.

We are going to use the following three classes for this demo.

Reverse Mapping Using AutoMapper in C#

To implement the Reverse Mapping using Automapper in C# we need to use the ReverseMap option as shown in the below image.

Reverse Mapping Using AutoMapper in C#

Below is the complete example.
using AutoMapper;
namespace AutoMapperDemo
{
class Program
{
static void Main(string[] args)
{
//Step1: Initialize the Mapper
InitializeAutomapper();
//Step2: Create the Order Request
var OrderRequest = CreateOrderRequest();
//Step3: Map the OrderRequest object to Order DTO
var orderDTOData = Mapper.Map<Order, OrderDTO>(OrderRequest);
//Step4: Print the OrderDTO Data
Console.WriteLine("After Mapping - OrderDTO Data");
Console.WriteLine("OrderId : " + orderDTOData.OrderId);
Console.WriteLine("NumberOfItems : " + orderDTOData.NumberOfItems);
Console.WriteLine("TotalAmount : " + orderDTOData.TotalAmount);
Console.WriteLine("CustomerId : " + orderDTOData.CustomerId);
Console.WriteLine("Name : " + orderDTOData.Name);
Console.WriteLine("Postcode : " + orderDTOData.Postcode);
Console.WriteLine("MobileNo : " + orderDTOData.MobileNo);
Console.WriteLine();
//Step5: modify the OrderDTO data
orderDTOData.OrderId = 10;
orderDTOData.NumberOfItems = 20;
orderDTOData.TotalAmount = 2000;
orderDTOData.CustomerId = 5;
orderDTOData.Name = "Smith";
orderDTOData.Postcode = "12345";
//Step6: Reverse Map
Mapper.Map(orderDTOData, OrderRequest);
//Step7: Print the Order Data
Console.WriteLine("After Reverse Mapping - Order Data");
Console.WriteLine("OrderNo : " + OrderRequest.OrderNo);
Console.WriteLine("NumberOfItems : " + OrderRequest.NumberOfItems);
Console.WriteLine("TotalAmount : " + OrderRequest.TotalAmount);
Console.WriteLine("CustomerId : " + OrderRequest.Customer.CustomerID);
Console.WriteLine("FullName : " + OrderRequest.Customer.FullName);
Console.WriteLine("Postcode : " + OrderRequest.Customer.Postcode);
Console.WriteLine("ContactNo : " + OrderRequest.Customer.ContactNo);
Console.ReadLine();
}
static void InitializeAutomapper()
{
Mapper.Initialize(config =>
{
config.CreateMap<Order, OrderDTO>()
//OrderId is different so map them using For Member
.ForMember(dest => dest.OrderId, act => act.MapFrom(src => src.OrderNo))
//Customer is a Complex type, so Map Customer to Simple type using For Membee
.ForMember(dest => dest.Name, act => act.MapFrom(src => src.Customer.FullName))
.ForMember(dest => dest.Postcode, act => act.MapFrom(src => src.Customer.Postcode))
.ForMember(dest => dest.MobileNo, act => act.MapFrom(src => src.Customer.ContactNo))
.ForMember(dest => dest.CustomerId, act => act.MapFrom(src => src.Customer.CustomerID))
.ReverseMap();
});
}
private static Order CreateOrderRequest()
{
return new Order
{
OrderNo = 101,
NumberOfItems = 3,
TotalAmount = 1000,
Customer = new Customer()
{
CustomerID = 777,
FullName = "James Smith",
Postcode = "755019",
ContactNo = "1234567890"
},
};
}
}
public class Order
{
public int OrderNo { get; set; }
public int NumberOfItems { get; set; }
public int TotalAmount { get; set; }
public Customer Customer { get; set; }
}
public class Customer
{
public int CustomerID { get; set; }
public string FullName { get; set; }
public string Postcode { get; set; }
public string ContactNo { get; set; }
}
public class OrderDTO
{
public int OrderId { get; set; }
public int NumberOfItems { get; set; }
public int TotalAmount { get; set; }
public int CustomerId { get; set; }
public string Name { get; set; }
public string Postcode { get; set; }
public string MobileNo { get; set; }
}
}

When we run the application, it displays the data as expected as shown in the below image.

Reverse Mapping Using AutoMapper in C#

Let’s change the Models as shown below.

Reverse Mapping Using AutoMapper in C#

As you can see from the above image, now the complex type property is present in the OrderDTO type and primitive types are present in the Order Type. Now let’s implement the AutoMapper ReverseMap() function and see whether we get the results as expected or not.

Let’s Modify the Mapper initialization to implement mapping and reverse mapping for the above types as shown in the below image.

Reverse Mapping Using AutoMapper in C#

Below is the code for the complete example
using AutoMapper;
namespace AutoMapperDemo
{
class Program
{
static void Main(string[] args)
{
//Step1: Initialize the Mapper
InitializeAutomapper();
//Step2: Create the Order Request
var OrderRequest = CreateOrderRequest();
//Step3: Map the OrderRequest object to Order DTO
var orderDTOData = Mapper.Map<Order, OrderDTO>(OrderRequest);
//Step4: Print the OrderDTO Data
Console.WriteLine("After Mapping - OrderDTO Data");
Console.WriteLine("OrderId : " + orderDTOData.OrderId);
Console.WriteLine("NumberOfItems : " + orderDTOData.NumberOfItems);
Console.WriteLine("TotalAmount : " + orderDTOData.TotalAmount);
Console.WriteLine("CustomerId : " + orderDTOData.customer.CustomerID);
Console.WriteLine("FullName : " + orderDTOData.customer.FullName);
Console.WriteLine("Postcode : " + orderDTOData.customer.Postcode);
Console.WriteLine("ContactNo : " + orderDTOData.customer.ContactNo);
Console.WriteLine();
//Step5: modify the OrderDTO data
orderDTOData.OrderId = 10;
orderDTOData.NumberOfItems = 20;
orderDTOData.TotalAmount = 2000;
orderDTOData.customer.CustomerID = 5;
orderDTOData.customer.FullName = "James Smith";
orderDTOData.customer.Postcode = "12345";
//Step6: Reverse Map
Mapper.Map(orderDTOData, OrderRequest);
//Step7: Print the Order Data
Console.WriteLine("After Reverse Mapping - Order Data");
Console.WriteLine("OrderNo : " + OrderRequest.OrderNo);
Console.WriteLine("NumberOfItems : " + OrderRequest.NumberOfItems);
Console.WriteLine("TotalAmount : " + OrderRequest.TotalAmount);
Console.WriteLine("CustomerId : " + OrderRequest.CustomerId);
Console.WriteLine("Name : " + OrderRequest.Name);
Console.WriteLine("Postcode : " + OrderRequest.Postcode);
Console.WriteLine("MobileNo : " + OrderRequest.MobileNo);
Console.ReadLine();
}
static void InitializeAutomapper()
{
Mapper.Initialize(config =>
{
config.CreateMap<Order, OrderDTO>()
.ForMember(dest => dest.OrderId, act => act.MapFrom(src => src.OrderNo))
.ForMember(dest => dest.customer, act => act.MapFrom(src => new Customer()
{
CustomerID = src.CustomerId,
FullName = src.Name,
Postcode = src.Postcode,
ContactNo = src.MobileNo
}))
.ReverseMap();
});
}
private static Order CreateOrderRequest()
{
return new Order
{
OrderNo = 101,
NumberOfItems = 3,
TotalAmount = 1000,
CustomerId = 777,
Name = "James Smith",
Postcode = "755019",
MobileNo = "1234567890"
};
}
}
public class Order
{
public int OrderNo { get; set; }
public int NumberOfItems { get; set; }
public int TotalAmount { get; set; }
public int CustomerId { get; set; }
public string Name { get; set; }
public string Postcode { get; set; }
public string MobileNo { get; set; }
}
public class Customer
{
public int CustomerID { get; set; }
public string FullName { get; set; }
public string Postcode { get; set; }
public string ContactNo { get; set; }
}
public class OrderDTO
{
public int OrderId { get; set; }
public int NumberOfItems { get; set; }
public int TotalAmount { get; set; }
public Customer customer { get; set; }
}
}

Now run the application and see the output.

Reverse Mapping Using AutoMapper in C#

As you can see from the above output, the automapper reverse mapping work as expected for the primitive types but it’s not working with the complex type.

So when both classes have members that are named equally then the AutoMapper ReverseMap() function works as expected. But if classes contain members that are different and not mapped via the default (per naming) mapping then this does not work as expected.  If we want to make the two-way mapping work as expected then we need to do the Mapping via ForMember.

So let’s modify the Mapper initialization to tell the mapping for the complex type as shown in the below image.

Reverse Mapping Using AutoMapper in C#

Below is the complete code.
using AutoMapper;
namespace AutoMapperDemo
{
class Program
{
static void Main(string[] args)
{
//Step1: Initialize the Mapper
InitializeAutomapper();
//Step2: Create the Order Request
var OrderRequest = CreateOrderRequest();
//Step3: Map the OrderRequest object to Order DTO
var orderDTOData = Mapper.Map<Order, OrderDTO>(OrderRequest);
//Step4: Print the OrderDTO Data
Console.WriteLine("After Mapping - OrderDTO Data");
Console.WriteLine("OrderId : " + orderDTOData.OrderId);
Console.WriteLine("NumberOfItems : " + orderDTOData.NumberOfItems);
Console.WriteLine("TotalAmount : " + orderDTOData.TotalAmount);
Console.WriteLine("CustomerId : " + orderDTOData.customer.CustomerID);
Console.WriteLine("FullName : " + orderDTOData.customer.FullName);
Console.WriteLine("Postcode : " + orderDTOData.customer.Postcode);
Console.WriteLine("ContactNo : " + orderDTOData.customer.ContactNo);
Console.WriteLine();
//Step5: modify the OrderDTO data
orderDTOData.OrderId = 10;
orderDTOData.NumberOfItems = 20;
orderDTOData.TotalAmount = 2000;
orderDTOData.customer.CustomerID = 5;
orderDTOData.customer.FullName = "James Smith";
orderDTOData.customer.Postcode = "12345";
//Step6: Reverse Map
Mapper.Map(orderDTOData, OrderRequest);
//Step7: Print the Order Data
Console.WriteLine("After Reverse Mapping - Order Data");
Console.WriteLine("OrderNo : " + OrderRequest.OrderNo);
Console.WriteLine("NumberOfItems : " + OrderRequest.NumberOfItems);
Console.WriteLine("TotalAmount : " + OrderRequest.TotalAmount);
Console.WriteLine("CustomerId : " + OrderRequest.CustomerId);
Console.WriteLine("Name : " + OrderRequest.Name);
Console.WriteLine("Postcode : " + OrderRequest.Postcode);
Console.WriteLine("MobileNo : " + OrderRequest.MobileNo);
Console.ReadLine();
}
static void InitializeAutomapper()
{
Mapper.Initialize(config =>
{
config.CreateMap<Order, OrderDTO>()
.ForMember(dest => dest.OrderId, act => act.MapFrom(src => src.OrderNo))
.ForMember(dest => dest.customer, act => act.MapFrom(src => new Customer()
{
CustomerID = src.CustomerId,
FullName = src.Name,
Postcode = src.Postcode,
ContactNo = src.MobileNo
}))
.ReverseMap()
.ForMember(dest => dest.CustomerId, act => act.MapFrom(src => src.customer.CustomerID))
.ForMember(dest => dest.Name, act => act.MapFrom(src => src.customer.FullName))
.ForMember(dest => dest.MobileNo, act => act.MapFrom(src => src.customer.ContactNo))
.ForMember(dest => dest.Postcode, act => act.MapFrom(src => src.customer.Postcode));
});
}
private static Order CreateOrderRequest()
{
return new Order
{
OrderNo = 101,
NumberOfItems = 3,
TotalAmount = 1000,
CustomerId = 777,
Name = "James Smith",
Postcode = "755019",
MobileNo = "1234567890"
};
}
}
public class Order
{
public int OrderNo { get; set; }
public int NumberOfItems { get; set; }
public int TotalAmount { get; set; }
public int CustomerId { get; set; }
public string Name { get; set; }
public string Postcode { get; set; }
public string MobileNo { get; set; }
}
public class Customer
{
public int CustomerID { get; set; }
public string FullName { get; set; }
public string Postcode { get; set; }
public string ContactNo { get; set; }
}
public class OrderDTO
{
public int OrderId { get; set; }
public int NumberOfItems { get; set; }
public int TotalAmount { get; set; }
public Customer customer { get; set; }
}
}

Now run the application and you will see the output as expected as shown in the below image.

Reverse Mapping Using AutoMapper in C#

In the next article, I will discuss Conditional Mapping using AutoMapper in C# with examples.

SUMMARY:

In this article, I try to explain Reverse Mapping Using AutoMapper in C# with some examples. I hope this Reverse Mapping Using AutoMapper in C# article will help you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *