@@ -10,7 +10,7 @@ namespace AutoMapper.Mappers
1010{
1111 public class EquivalentExpressionAddRemoveCollectionMapper : IConfigurationObjectMapper
1212 {
13- private readonly CollectionMapper CollectionMapper = new CollectionMapper ( ) ;
13+ private readonly CollectionMapper _collectionMapper = new CollectionMapper ( ) ;
1414
1515 public IConfigurationProvider ConfigurationProvider { get ; set ; }
1616
@@ -62,37 +62,50 @@ public static TDestination Map<TSource, TSourceItem, TDestination, TDestinationI
6262 return destination ;
6363 }
6464
65- private static readonly MethodInfo MapMethodInfo = typeof ( EquivalentExpressionAddRemoveCollectionMapper ) . GetRuntimeMethods ( ) . First ( _ => _ . IsStatic ) ;
65+ private static readonly MethodInfo _mapMethodInfo = typeof ( EquivalentExpressionAddRemoveCollectionMapper ) . GetRuntimeMethods ( ) . Single ( _ => _ . IsStatic && _ . Name == nameof ( Map ) ) ;
6666
6767 public bool IsMatch ( TypePair typePair )
6868 {
69- if ( typePair . SourceType . IsEnumerableType ( )
70- && typePair . DestinationType . IsCollectionType ( ) )
71- {
72- var realType = new TypePair ( TypeHelper . GetElementType ( typePair . SourceType ) , TypeHelper . GetElementType ( typePair . DestinationType ) ) ;
73-
74- return realType != typePair
75- && this . GetEquivalentExpression ( realType . SourceType , realType . DestinationType ) != null ;
76- }
69+ return typePair . SourceType . IsEnumerableType ( )
70+ && typePair . DestinationType . IsCollectionType ( ) ;
71+ }
7772
78- return false ;
73+ public TypePair GetAssociatedTypes ( TypePair initialTypes )
74+ {
75+ return new TypePair ( TypeHelper . GetElementType ( initialTypes . SourceType ) , TypeHelper . GetElementType ( initialTypes . DestinationType ) ) ;
7976 }
8077
8178 public Expression MapExpression ( IConfigurationProvider configurationProvider , ProfileMap profileMap , IMemberMap memberMap ,
8279 Expression sourceExpression , Expression destExpression , Expression contextExpression )
8380 {
81+ IObjectMapper nextMapper = _collectionMapper ;
82+ var typePair = new TypePair ( sourceExpression . Type , destExpression . Type ) ;
83+ var mappers = new List < IObjectMapper > ( configurationProvider . GetMappers ( ) ) ;
84+ for ( var i = mappers . IndexOf ( this ) + 1 ; i < mappers . Count ; i ++ )
85+ {
86+ var mapper = mappers [ i ] ;
87+ if ( mapper . IsMatch ( typePair ) )
88+ {
89+ nextMapper = mapper ;
90+ break ;
91+ }
92+ }
93+ var nextMapperExpression = nextMapper . MapExpression ( configurationProvider , profileMap , memberMap , sourceExpression , destExpression , contextExpression ) ;
94+
8495 var sourceType = TypeHelper . GetElementType ( sourceExpression . Type ) ;
8596 var destType = TypeHelper . GetElementType ( destExpression . Type ) ;
8697
87- var method = MapMethodInfo . MakeGenericMethod ( sourceExpression . Type , sourceType , destExpression . Type , destType ) ;
8898 var equivalencyExpression = this . GetEquivalentExpression ( sourceType , destType ) ;
99+ if ( equivalencyExpression == null )
100+ {
101+ return nextMapperExpression ;
102+ }
89103
90- var equivalencyExpressionConst = Constant ( equivalencyExpression ) ;
91- var map = Call ( null , method , sourceExpression , destExpression , contextExpression , equivalencyExpressionConst ) ;
104+ var method = _mapMethodInfo . MakeGenericMethod ( sourceExpression . Type , sourceType , destExpression . Type , destType ) ;
105+ var map = Call ( null , method , sourceExpression , destExpression , contextExpression , Constant ( equivalencyExpression ) ) ;
92106
93107 var notNull = NotEqual ( destExpression , Constant ( null ) ) ;
94- var collectionMap = CollectionMapper . MapExpression ( configurationProvider , profileMap , memberMap , sourceExpression , destExpression , contextExpression ) ;
95- return Condition ( notNull , map , Convert ( collectionMap , destExpression . Type ) ) ;
108+ return Condition ( notNull , map , Convert ( nextMapperExpression , destExpression . Type ) ) ;
96109 }
97110 }
98111}
0 commit comments