Skip to content

Commit 4a89390

Browse files
committed
Rewrite the logic to find the correct equivalend expression to avoid circular loop in AM.
1 parent ec3b19f commit 4a89390

File tree

1 file changed

+29
-16
lines changed

1 file changed

+29
-16
lines changed

src/AutoMapper.Collection/Mappers/EquivalentExpressionAddRemoveCollectionMapper.cs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)