Mapping between inheritance and composition with Automapper

40 views Asked by At

I have recently started using Automapper in my work project to map between database objects and business objects. The business objects already exist and their structure cannot be changed (unfortunatley). They use a multiple levels of inheritance. On the database side, I have multiple objects that use composition to emulate the structural hierarchy of the business objects.

Most mappings work fine, but I'm struggling to map between the composition classes and the inherited classes. I'll give an example; Lets say I have class A that inherits from class B that may or may not be abstract. Then, on the database side, I have the class ADbo (database object) that has a property that references BDbo. i.e.

// Business layer objects
public class A : B
{
    public int SomeValue { get; set; }
}

public abstract class B
{
    public int OtherValue { get; set; }
}
// Database layer objects
public class ADbo
{
    public int SomeValue { get; set; }
    
    public BDbo Data { get; set; }
}

public class BDbo
{
    public int OtherValue { get; set; }
}

The classes have mappings similar to:

var config = new MapperConfiguration(cfg => {
    cfg.CreateMap<A, ADbo>().ReverseMap();
    cfg.CreatMap<B, BDbo>().ReverseMap();
});

The AutoMapper docs have examples for mapping inheritance and composition, but not from one to the other. I was also looking into value converters but couldn't figure out how to do it without the configuration already being configured.

So, has anyone ever tried to map this strange case or know of a possible route I could take? Or, is this simply not within the abilities of AutoMapper to handle?

1

There are 1 answers

0
RezaNoei On

You can user ForMember method to tell automapper about the conversion of any specific property. for example:

var config = new MapperConfiguration(cfg => {
    cfg.CreateMap<A, ADbo>().ForMember(P => P.Data, Opt => Opt.MapFrom(Q => new BDbo() { OtherValue = Q.OtherValue }));
});

For BDbo you don't need extra stuffs, as long as their property names and types are identically same.