In v12, PropertyMap.SourceMember returns SourceMembers.First() in some cases #4080
-
Version: 12.0.0Expected behaviorExpecting the source member type to match the mapped property type. Actual behaviorThe source member type returns the source property's parent type (in one case). It seems related to mapping by convention which seems to be obsolete (trying to map by convention throws the "Unmapped members were found" Steps to reproduce public class TestSourceMember
{
[Fact]
public void Returns_SourceMember_Dot_First()
{
//Arrange
var config = GetConfiguration();
config.AssertConfigurationIsValid();
var mapper = config.CreateMapper();
TypeMap typeMap = config.Internal().ResolveTypeMap(typeof(Player), typeof(PlayerModel));
PropertyMap propertyMapStatsASpeed = typeMap.PropertyMaps.Single(item => item.DestinationName == "StatsASpeed");
PropertyMap propertyMapStatsAPower = typeMap.PropertyMaps.Single(item => item.DestinationName == "StatsAPower");
Type sourceMemberStatsASpeed = propertyMapStatsASpeed.SourceMember.GetMemberType();
Type sourceMemberStatsAPower = propertyMapStatsAPower.SourceMember.GetMemberType();
Assert.Equal(typeof(int), sourceMemberStatsASpeed);
Assert.Equal(typeof(int), sourceMemberStatsAPower);/*Type is Stats*/
}
public class Player
{
public string Name { get; set; }
public Stats StatsA { get; set; }
}
public class Stats
{
public int SpeedValue { get; set; }
public int Power { get; set; }/*Works if renamed to PowerValue*/
}
public class PlayerModel
{
public string Name { get; set; }
public int StatsASpeed { get; set; }
public int StatsAPower { get; set; }
}
MapperConfiguration GetConfiguration()
=> new MapperConfiguration(cfg =>
{
cfg.CreateMap<Player, PlayerModel>()
.IncludeMembers(p => p.StatsA);
cfg.CreateMap<Stats, PlayerModel>()
.ForMember(d => d.Name, opt => opt.Ignore())
.ForMember(d => d.StatsASpeed, opt => opt.MapFrom(s => s.SpeedValue))
.ForMember(d => d.StatsAPower, opt => opt.MapFrom(s => s.Power));
});
} The workaround is to use |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
You either use the default flattening or |
Beta Was this translation helpful? Give feedback.
You either use the default flattening or
IncludeMembers
. Both at the same time makes no sense.If
SourceMember
doesn't work for you, write your own version. We use it for source validation. So it can return whatever works for the higher level tests.