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.
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.
That looks pretty sweet. While the GetTotal was automagically mapped, I’m more impressed with the CustomerDisplayName as it had to traverse across the objects. Anyway, informative post…thanks.
AutoMapper use from Reflection ?
Its a really a nice example for help regarding DTO,
However i would recommend that the author should upload a complete small project in which data is accessed on web pages from database using DTO..
It would be useful on auto mapper configuration as well.