I have a project using AutoMapper 3.1.1, I was able to isolate the problem that I encountered.
Here are my test classes:
class BaseClass { public string PropertyA { get; set; } } class DerivedClass: BaseClass { public string PropertyB { get; set; } } class ContainerClass { public DerivedClass ComplexProperty { get; set; } public string PropertyC { get; set; } } class SourceClass { public string PropertyA { get; set; } public string PropertyB { get; set; } public string PropertyC { get; set; } }
Here are my display rules:
Mapper.CreateMap<SourceClass, ContainerClass>() .ForMember(d => d.ComplexProperty, o => o.MapFrom(s => Mapper.Map<DerivedClass>(s))) .AfterMap((s, d) => System.Diagnostics.Debug.WriteLine("SourceClass-> ContainerClass mapped")); Mapper.CreateMap<SourceClass, DerivedClass>() .AfterMap((s, d) => System.Diagnostics.Debug.WriteLine("SourceClass -> DerivedClass mapped")); Mapper.CreateMap<BaseClass, DerivedClass>() .AfterMap((s, d) => System.Diagnostics.Debug.WriteLine("BaseClass -> DerivedClass mapped"));
Here is my code:
var source = new SourceClass { PropertyA = "ValueA", PropertyB = "ValueB", PropertyC = "ValueC", }; var destination = Mapper.Map<ContainerClass>(source); Console.WriteLine("PropertyA: " + destination?.ComplexProperty?.PropertyA); Console.WriteLine("PropertyB: " + destination?.ComplexProperty?.PropertyB); Console.WriteLine("PropertyC: " + destination?.PropertyC);
Output:
PropertyA: ValueA PropertyB: PropertyC: ValueC
I expected PropertyB to be "ValueB", but instead it is null. This is because, for some reason, the iterator from BaseClass to DerivedClass is being executed. My debug output is as follows:
SourceClass -> DerivedClass mapped BaseClass -> DerivedClass mapped SourceClass -> ContainerClass mapped
Why does AutoMapper render BaseClass -> DerivedClass?
UPDATE: Thanks to Marius. Now I know that mapping from BaseClass to DerivedClass is invalid. I cannot delete this matching rule because I need it for my application. As an exception, I added Ignore for the PropertyB:
Mapper.CreateMap<BaseClass, DerivedClass>() .ForMember(d => d.PropertyB, o => o.Ignore()) .AfterMap((s, d) => System.Diagnostics.Debug.WriteLine("BaseClass -> DerivedClass mapped"));
Now Mapper.AssertConfigurationIsValid(); no longer throws an exception. But the original question is still standing. Why does AutoMapper render BaseClass -> DerivedClass?