It's probably easiest if I explain this with a (fictitious) example.
I have an nHibernate model that contains an Order object. This Order object contains a collection of OrderItem nHibernate objects.
I have an Order ViewModel which contains a collection of OrderItemDto's (which are really just POCOs).
In my UI, I display an order object and a list of OrderItems and they are editable in the list. Model-binding takes care of populating the OrderViewModel and OrderItemDto collection.
Here is my model
namespace nHibernateModel
{
public class Order
{
private readonly IList<OrderItem> _OrderItems;
public int Id { get; set; }
public Order()
{
_OrderItems = new List<OrderItem>();
}
public IList<OrderItem> OrderItems
{
/* Setter does not exist to satisfy CA2227*/
get
{
return _OrderItems;
}
}
public void AddOrderItem(OrderItem orderItem)
{
//Set bi-directional relationships
if (_OrderItems.Contains(orderItem))
return;
orderItem.Order = this;
_OrderItems.Add(orderItem);
}
}
public class OrderItem
{
private readonly Order _Order;
public int Id { get; set; }
public Order Order
{
get { return _Order; }
set { value.OrderItems.Add(this); }
}
}
}
Here is my view-model/dto
namespace ViewModels
{
public class OrderViewModel
{
public OrderViewModel()
{
OrderItemDtos = new List<OrderItemDto>() ;
}
public IList<OrderItemDto> OrderItemDtos;
public int Id { get; set; }
}
public class OrderItemDto
{
public int Id { get; set; }
}
}
My issue is how to map the collection of OrderItemDto's to a collection of OrderItem objects that are attached to the order. I want control over the life-cycle of orderItem objects. IE, if the OrderItemDto has an Id, I want to get the orderItem from a repository. If it does not exist I want to create a new one and set its order property to the parent order.
Here is the pseudo code for what I think I want:
public class OrderModelToDtoMap
{
public OrderModelToDtoMap()
{
Mapper.CreateMap<OrderItemDto, OrderItem>();
Mapper.CreateMap<OrderViewModel, Order>()
.ForMember(dest => dest.OrderItems,
opt => opt.ResolveUsing(OrderItemDtosToOrderItemResolver)(src => src.OrderItemDtos));
}
private class OrderItemDtosToOrderItemResolver : IValueResolver
{
protected override ResolveCore(IList<OrderItemDto> source, Order order)
{
foreach (OrderItemDto orderItemDto in source)
{
OrderItem orderItem;
if (orderItemDto.Id == null)
{
orderItem = new OrderItem();
orderItem.Order = order;
}
else
{
OrderItemRepository.Get(orderItemDto.Id);
}
/* Map other properties */
}
}
}
But obviously this does not work because IValueResolver does not work like this.
This How to assign parent reference to a property in a child with AutoMapper is kind of similar, but does not allow me to get OrderItems out of the repository if they already exist.
Thanks, dave