GavKilbride
GavKilbride

Reputation: 1569

Automapper inheritance mapping not working after upgrade. V3.3.1.0 -> V4.0.4.0

I want to map multiple domain objects to their responding DTO's

Domain

public abstract class Order
{
    public int Id { get; set; }
}
public class OnlineOrder : Order
{
    public string Referrer { get; set; }
}
public class MailOrder : Order
{
    public string Address { get; set; }
}

DTO

public abstract class OrderDto
{
    public int Id { get; set; }
}
public class OnlineOrderDto : OrderDto
{
    public string Referrer { get; set; }
}
public class MailOrderDto : OrderDto
{
    public string Address { get; set; }
}

Map Definition

Mapper.CreateMap<Order, OrderDto>()
    .Include<OnlineOrder, OnlineOrderDto>()
    .Include<MailOrder, MailOrderDto>();
Mapper.CreateMap<OnlineOrder, OrderDto>();
Mapper.CreateMap<MailOrder, OrderDto>();

Object Mapping

var orders = new List<Order>()
    {
        new OnlineOrder { Referrer = "Google", Id = 123 }, 
        new MailOrder() { Address = "1600 Amphitheatre Parkway", Id = 124}
    };
var mapped = Mapper.Map<List<OrderDto>>(orders);

I would expect Automapper to be able to discern the type passed in and using the definition specified to choose the appropriate source and destination. i.e. an OnlineOrder would be mapped to an OnlineOrderDto and a MailOrder I would be mapped to a MailOrderDto. This is not the case as I get an "Instances of abstract classes cannot be created" error. I'm almost certain I have used a similar pattern before but I've hit a wall and any help would be appreciated.

Update: It would seem that this is only a problem after upgrading to the latest version of Automapper V4.0.4.0.

Upvotes: 2

Views: 1285

Answers (1)

vendettamit
vendettamit

Reputation: 14677

Yeah this is a known issue and would require a code change. Change your initialization to -

Mapper.Initialize(cfg =>
        {
            cfg .CreateMap<Order, OrderDto>()
              .Include<OnlineOrder, OnlineOrderDto>()
              .Include<MailOrder, MailOrderDto>();
              cfg.CreateMap<OnlineOrder, OrderDto>();
              cfg.CreateMap<MailOrder, OrderDto>();
        });

Update ver: bug fixed for 4.1.0 milestone

Alternatively, you can do is seal the mappings.

Mapper.Configuration.Seal();

Upvotes: 2

Related Questions