Creating DTOs using AutoMapper

There is one small and nice object to object mapper called AutoMapper. I gave it a little try and I found it very useful. Specially if you have web service and you are using DTOs to move data between client and server. Good news is that AutoMapper is able to perform these mappings and you don’t have to write more code than couple of lines. Let’s see example.

Suppose you have following classes: Order, OrderLine, Customer and OrderDto. OrderDto is DTO we are using to send order data to client. I have really simple classes for example purposes, so don’t try to find any good practices here.


public class Party
{
   
public string DisplayName { get; set
; }
}

public class Order
{
   
public string OrderNo { get; set
; }
   
public DateTime OrderDate { get; set
; }
   
public List<OrderLine> OrderLines { get; set
; }
   
public Party Customer { get; set
; }

   
public decimal
GetTotal()
    {
       
var query = from line in
OrderLines
                   
select
line;
       
return query.Sum<OrderLine
>(a => a.Sum);
    }
}

public class OrderLine
{
   
public string LineItem { get; set
; }
   
public decimal Sum { get; set
; }
}

public class OrderDTO
{
   
public string CustomerDisplayName { get; set
; }
   
public string OrderNo { get; set
; }
   
public DateTime OrderDate { get; set
; }
   
public decimal Total { get; set
; }

   
public static OrderDTO Create(Order
order)
    {
       
var dto = new OrderDTO
();
        dto.CustomerDisplayName = order.Customer.DisplayName;
        dto.OrderDate = order.OrderDate;
        dto.OrderNo = order.OrderNo;
        dto.Total = order.GetTotal();
       
return dto;
    }
}

DTO creation and initialization is done in OrderDTO.Create() method. The code here is short if we compare it to real life DTOs. And usually we write this code manually. Here is the code that creates order and asks order DTO from OrderDTO class.


public void ClassicDTOExample()
{
   
var party = new Party
();
    party.DisplayName =
"Smith, John"
;

   
var order = new Order
();
    order.OrderDate = DateTime.Now;
    order.Customer = party;
    order.OrderNo =
"102"
;

    order.OrderLines =
new List<OrderLine
>();
    order.OrderLines.Add(
           
new OrderLine() { LineItem = "Tea"
, Sum = 10 }
        );
    order.OrderLines.Add(
           
new OrderLine() { LineItem = "Coffee"
, Sum = 15 }
        );
    order.OrderLines.Add(
           
new OrderLine() { LineItem = "Juice"
, Sum = 5 }
        );

   
var dto = OrderDTO.Create(order);
}

Now let’s see how AutoMapper works. All we have to is to define mappings and use names of class members so auto mapping can take place. We need to modify OrderDTO class and remove Create() method. Our example code also changes a little bit.


public class OrderDTO
{
   
public string CustomerDisplayName { get; set
; }
   
public string OrderNo { get; set
; }
   
public DateTime OrderDate { get; set
; }
   
public decimal Total { get; set
; }
}

public void
AutoMapperDTOExample()
{
   
var party = new Party
();
    party.DisplayName =
"Smith, John"
;

   
var order = new Order
();
    order.OrderDate = DateTime.Now;
    order.Customer = party;
    order.OrderNo =
"102"
;

    order.OrderLines =
new List<OrderLine
>();
    order.OrderLines.Add(
           
new OrderLine() { LineItem = "Tea"
, Sum = 10 }
        );
    order.OrderLines.Add(
           
new OrderLine() { LineItem = "Coffee"
, Sum = 15 }
        );
    order.OrderLines.Add(
           
new OrderLine() { LineItem = "Juice"
, Sum = 5 }
        );

   
Mapper.CreateMap<Order, OrderDTO
>();

   
var dto = Mapper.Map<Order, OrderDTO>(order);
}

As you can see we have now one method less to test and worry about. Pay attention to DTO member names – I chose names so that AutoMapper can understand what members of order and OrderDTO match. If I look what is inside order DTO created by AutoMapper I see something like this in my locals window.

AutoMapper locals

The most interesting here is OrderDTO member Total. If you look at code above you can see that Order class has method GetTotal(). The value of GetTotal() was automatically mapped to Total property of OrderDTO class.

Although AutoMapper is pretty new and I’m not sure how good it is for using in production code I am sure that another tool for everydays work is coming.


Leave a Reply

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