Lets say I have these models
public class Mouse
{
public string Cheese { get; set; }
}
public class Cat
{
public string Hairball { get; set; }
}
public class Dog
{
public string ChewyToy { get; set; }
}
And I map a Mouse to a Cat then a Cat to a Dog:
Mapper.CreateMap<Mouse, Cat>().ForMember(m => m.Hairball, o => o.MapFrom(src => src.Cheese));
Mapper.CreateMap<Cat, Dog>().ForMember(m => m.ChewyToy, o => o.MapFrom(src => src.Hairball));
By extension, a Mouse should also be mapped to a Dog, right? When I try to map between the two:
var mouse = new Mouse() { Cheese = "Eat me" };
Dog dog = Mapper.Map<Mouse, Dog>(mouse);
I get an exception:
Trying to map App_Start.MapConfig+Mouse to App_Start.MapConfig+Dog. Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
How do I do this with out explicitly creating a map between a Mouse to a Dog? This is a simple example of a bigger issue. I'm also open to switching frameworks such as Value Injector, Glue, etc if they support this behavior.
The answer is simple: you can't.
Automapper has pretty straightforward logic for mapping objects. When you are adding new mapping:
New
TypeMap
is created and added to list of type maps. Yes, there is simple list. And eachTypeMap
has two properties:DestinationType
andSourceType
. Nothing in the middle. When you are trying to map some object, then list is simply searched for firstTypeMap
which has exactly same source and destination types, as specified in your mapping. It is done with following method (ConfigurationStore class is responsible for holding configured mappings):So, for your sample there will be two
TypeMap
objects in list, and of course none of them matches condition ofDestinationType
equalt toDog
andSourceType
equal toMouse
.