From 6ff7425b839c7c19a69ed888e295616dd1f90964 Mon Sep 17 00:00:00 2001 From: Lucian Bargaoanu Date: Wed, 9 Feb 2022 13:24:38 +0200 Subject: [PATCH] prefer derived interfaces --- .../Configuration/MapperConfiguration.cs | 14 +++++- src/UnitTests/InterfaceMapping.cs | 50 +++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/AutoMapper/Configuration/MapperConfiguration.cs b/src/AutoMapper/Configuration/MapperConfiguration.cs index f05acee714..d44b28f705 100644 --- a/src/AutoMapper/Configuration/MapperConfiguration.cs +++ b/src/AutoMapper/Configuration/MapperConfiguration.cs @@ -300,15 +300,25 @@ private TypeMap GetTypeMap(TypePair initialTypes) static List GetTypeInheritance(Type type) { var interfaces = type.GetInterfaces(); + var lastIndex = interfaces.Length - 1; var types = new List(interfaces.Length + 2) { type }; Type baseType = type; while ((baseType = baseType.BaseType) != null) { types.Add(baseType); + foreach (var interfaceType in baseType.GetInterfaces()) + { + var interfaceIndex = Array.LastIndexOf(interfaces, interfaceType); + if (interfaceIndex != lastIndex) + { + interfaces[interfaceIndex] = interfaces[lastIndex]; + interfaces[lastIndex] = interfaceType; + } + } } - for(int index = interfaces.Length - 1; index >= 0; index--) + foreach (var interfaceType in interfaces) { - types.Add(interfaces[index]); + types.Add(interfaceType); } return types; } diff --git a/src/UnitTests/InterfaceMapping.cs b/src/UnitTests/InterfaceMapping.cs index b102a0b48b..c6360b0942 100644 --- a/src/UnitTests/InterfaceMapping.cs +++ b/src/UnitTests/InterfaceMapping.cs @@ -6,6 +6,56 @@ using Xunit; namespace AutoMapper.UnitTests.InterfaceMapping { + public class InterfaceInheritance : AutoMapperSpecBase + { + protected override MapperConfiguration CreateConfiguration() => new(cfg => + { + cfg.CreateMap() + .IncludeBase() + .IncludeBase(); + cfg.CreateMap(); + cfg.CreateMap(); + }); + [Fact] + public void Should_choose_the_derived_interface() + { + var source = new Source + { + Name = "Name", + PropertyA = "PropertyA", + PropertyB = "PropertyB" + }; + var destination = new Target(); + Mapper.Map(source, destination); + destination.Name.ShouldBe(source.Name); + destination.PropertyA.ShouldBe(source.PropertyA); + destination.PropertyB.ShouldBe(source.PropertyB); + } + public class Source + { + public string PropertyA { get; set; } + public string PropertyB { get; set; } + public string Name { get; set; } + } + public class Target : IProperties + { + public string PropertyA { get; set; } + public string PropertyB { get; set; } + public string Name { get; set; } + } + public interface IProperties : IPropertyA, IPropertyB + { + string Name { get; set; } + } + public interface IPropertyA + { + string PropertyA { get; set; } + } + public interface IPropertyB + { + string PropertyB { get; set; } + } + } public class MapToInterface : NonValidatingSpecBase { protected override MapperConfiguration CreateConfiguration() => new(c=>c.CreateMap>());