5

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

Community
  • 1
  • 1
Dave
  • 1,068
  • 12
  • 26

0 Answers0