Adding Inheritance to AutoMapper

Update: This is currently in the Automapper master, and will be included in the v2 release (hopefully Before/After map will also get included, patch submitted).

In my current project, we are leveraging AutoMapper a lot to map our Domain to Dto's. The major problem we are facing is that our mappings are getting quite complex and bloated, especially for flattened Dtos or Summaries which have properties that cover all the properties from the concrete types they come from. It seemed unnatural that I could define a mapping that looked like:

Mapper.CreateMap<ItemBase, ItemSummaryDto>()
    .ForMember(d => d.Description, m => m.MapFrom(s => s.ItemSummary))
    .Include<GeneralItem, GeneralItemSummaryDto>()
    .Include<SpecificItem, SpecificItemSummaryDto>();
Mapper.CreateMap<GeneralItem, GeneralItemSumaryDto>()
    .ForMember(d => d.GeneralProperty, m => m.MapFrom(s => s.Something));
Mapper.CreateMap<SpecificItem, SpecificItemSumaryDto>()
    .ForMember(d => d.SpecificProperty, m => m.MapFrom(s => s.Something));

And have the rest of the properties map by convention. The problem is that the .Include function is only used for type resolution. i.e. var dto = Mapper.Map(new GeneralItem()); Assert.IsInstanceOfType(dto); // Passes

If we validate our mapping we will find that Description is not mapped on GeneralItemSummaryDto and SpecificItemSummaryDto. This means out mapping ends up being:

Mapper.CreateMap<ItemBase, ItemSummaryDto>()
    .Include<GeneralItem, GeneralItemSummaryDto>()
    .Include<SpecificItem, SpecificItemSummaryDto>();
Mapper.CreateMap<GeneralItem, GeneralItemSumaryDto>()
    .ForMember(d => d.Description, m => m.MapFrom(s => s.ItemSummary))
    .ForMember(d => d.GeneralProperty, m => m.MapFrom(s => s.Something));
Mapper.CreateMap<SpecificItem, SpecificItemSumaryDto>()
    .ForMember(d => d.Description, m => m.MapFrom(s => s.ItemSummary))
    .ForMember(d => d.SpecificProperty, m => m.MapFrom(s => s.Something));

We have to duplicate the mapping of the Description property on both the items. For my current project this means our mappings are far more complicated than they need to be, and have massive amounts of duplicated ForMember(d=>d.Blah, m=>m.Ignore()) mappings because we have many flattened summary dtos which have properties from many of the concrete types that are mapped.

Unfortunately it ended up being quite a difficult task, and with our complex mappings my initial implementations resulted in a few issues. I am pretty sure I have got most of them and have created quite a few unit tests covering it. Especially with collections of a base type, holding different concrete types.

Is anyone interested in this functionality? If so let me know and I will create a proper Fork on Github and share my changes. I still need to cleanup the unit tests and the code a little bit as the AutoMapper codebase is really nice and I don't want to make it messy.

automapperinheritanceopen-source
Posted by: Jake Ginnivan
Last revised: 16 Aug, 2011 10:47 AM

Comments

Dave
Dave
21 Jul, 2011 07:53 AM

Interesting work, would be very interested in seeing the code! May very well help in my current project too.

Jeroen de Bekker
Jeroen de Bekker
09 Aug, 2011 12:01 PM

Hi Jake,

I am interested as well.

This is just what we need; we also stumbled upon the fact that Automapper does not support inheritance of the mapping configuration. Before doing it myself, I searched the internet for a brave soul who might already did this, and I found you. Good job! :-).

Kind regards, Jeroen

lewis p webb
lewis p webb
11 Aug, 2011 06:32 PM

I must agree with the rest of the camp; can't believe the first comment to this post was only weeks ago. I am very interested in seeing your code and the unit tests that you have built that verifies the inheritance automapping functionality. MANY THANKS!

12 Aug, 2011 12:33 AM

Hey guys,

I am on this, I have to pull the code out as it was a while ago I wrote it, and the automapper master has likely moved on a fair bit.

I will try to dig up both my changes to master, and the current 1.1 release and post it onto the Automapper mailing list, and here as well.

Jeroen de Bekker
Jeroen de Bekker
16 Aug, 2011 09:11 AM

For anyone interested: I discovered that Jake's inheritance implementation is already integrated in the Automapper's repository on GitHub: https://github.com/automapper/automapper. If you look to the commits you can see it has been merged from the 1.1 to the master on 2010-11-11. It's also present in the 3.5 branch if you're using .NET 3.5.

If you're fine with fetching a non-official release, you can get and use the most recent revision for now.

14 Jul, 2011 08:34 AM

Hi Jake,

I'm very surprised to be the first person to comment on this post. Inheritance is a key piece of functionality I feel AutoMapper needs and something that will help reduce many lines of duplicated mappings. For what it is worth, I would be very pleased to see this added to AutoMapper and would be interested in your implementation.

Regards John

Your Comments

Used for your gravatar. Not required. Will not be public.
Posting code? Indent it by four spaces to make it look nice. Learn more about Markdown.

Preview