In this part I will show how we can use a customer value formatter (CustomFormatter) to format our mapped data into single “Number of Order:” and plural “Number of Orders:”.
First the Domain and Dto (data transfer object)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
//Domain public class Order { public string OrderNo { get; set; } public Customer Customer { get; set; } public DateTime PurchaseDate { get; set; } public IEnumerable<OrderItems> LineItems { get; set; } public bool ShipToHomeAddress { get; set; } public decimal GetTotal() { return LineItems == null ? 0 : LineItems.Sum(x => x.GetTotalPrice()); } public Guid InternalId { get; set; } } //Dto public class NumberOfOrderDto { public string CustomerName { get; set; } public string NumberOfOrders { get; set; } } |
Now we will introduce a CustomResolver and Formatter, for the Formatter we are inheriting from IValueFormatter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//Resolver public class CustomOrderCount: ValueResolver<Order, int> { protected override int ResolveCore(Order source) { return source.LineItems.Count(); } } //Formatter public class FormatOrderCount: IValueFormatter { public string FormatValue(ResolutionContext context) { int num = (int)context.SourceValue; if (num <= 1) return "Number of Order: " + num; return "Number of Orders: " + num; } } |
For our mapping code we will use a block for options, so that after resolving the value, it would format it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public ActionResult NumberOfOrders() { var orders = _respository.GetAll(); orders.First().LineItems = new List<OrderItems>(); Mapper.CreateMap<Order, NumberOfOrderDto>() .ForMember(dest => dest.NumberOfOrders, opt => { opt.ResolveUsing<CustomOrderCount>(); opt.AddFormatter<FormatOrderCount>(); }); var model = Mapper.Map<IEnumerable<Order>, IEnumerable<NumberOfOrderDto>>(orders); return View(model); } //View <h2>NumberOfOrders</h2> @foreach (var order in Model) { <p> @order.CustomerName <br /> @order.NumberOfOrders <br /> </p> } |
From the view we can see that the first order is displaying Order rather than Orders.
In the last part of the series I will show how to move all your mapping code to startup, so that it would speed things up.
Previous Post
Part 1 (NullSubsitution)
Part 2 (Flattening by Convention)
Part 3 (Nested Mapping)
Part 4 (Projection)
Part 5 (CustomResolver)
[…] Automapper: Mapping objects Part 6 of 7 (CustomFormatter) […]
where is 7 out of 7?
http://taswar.zeytinsoft.com/automapper-mapping-objects-part-7-of-7-startup-registration/