Skip to content

Commit 724c1bc

Browse files
committed
Only find the next IObjectMapper if the equivalencyExpression is null.
1 parent 606d222 commit 724c1bc

File tree

1 file changed

+20
-17
lines changed

1 file changed

+20
-17
lines changed

src/AutoMapper.Collection/Mappers/EquivalentExpressionAddRemoveCollectionMapper.cs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Concurrent;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Linq.Expressions;
45
using System.Reflection;
@@ -63,6 +64,7 @@ public static TDestination Map<TSource, TSourceItem, TDestination, TDestinationI
6364
}
6465

6566
private static readonly MethodInfo _mapMethodInfo = typeof(EquivalentExpressionAddRemoveCollectionMapper).GetRuntimeMethods().Single(x => x.IsStatic && x.Name == nameof(Map));
67+
private static readonly ConcurrentDictionary<TypePair, IObjectMapper> _objectMapperCache = new ConcurrentDictionary<TypePair, IObjectMapper>();
6668

6769
public bool IsMatch(TypePair typePair)
6870
{
@@ -73,34 +75,35 @@ public bool IsMatch(TypePair typePair)
7375
public Expression MapExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, IMemberMap memberMap,
7476
Expression sourceExpression, Expression destExpression, Expression contextExpression)
7577
{
76-
IObjectMapper nextMapper = _collectionMapper;
77-
var typePair = new TypePair(sourceExpression.Type, destExpression.Type);
78-
var mappers = new List<IObjectMapper>(configurationProvider.GetMappers());
79-
for (var i = mappers.IndexOf(this) + 1; i < mappers.Count; i++)
80-
{
81-
var mapper = mappers[i];
82-
if (mapper.IsMatch(typePair))
83-
{
84-
nextMapper = mapper;
85-
break;
86-
}
87-
}
88-
var nextMapperExpression = nextMapper.MapExpression(configurationProvider, profileMap, memberMap, sourceExpression, destExpression, contextExpression);
89-
9078
var sourceType = TypeHelper.GetElementType(sourceExpression.Type);
9179
var destType = TypeHelper.GetElementType(destExpression.Type);
9280

9381
var equivalencyExpression = this.GetEquivalentExpression(sourceType, destType);
9482
if (equivalencyExpression == null)
9583
{
96-
return nextMapperExpression;
84+
var typePair = new TypePair(sourceExpression.Type, destExpression.Type);
85+
return _objectMapperCache.GetOrAdd(typePair, _ =>
86+
{
87+
var mappers = new List<IObjectMapper>(configurationProvider.GetMappers());
88+
for (var i = mappers.IndexOf(this) + 1; i < mappers.Count; i++)
89+
{
90+
var mapper = mappers[i];
91+
if (mapper.IsMatch(typePair))
92+
{
93+
return mapper;
94+
}
95+
}
96+
return _collectionMapper;
97+
})
98+
.MapExpression(configurationProvider, profileMap, memberMap, sourceExpression, destExpression, contextExpression);
9799
}
98100

99101
var method = _mapMethodInfo.MakeGenericMethod(sourceExpression.Type, sourceType, destExpression.Type, destType);
100102
var map = Call(null, method, sourceExpression, destExpression, contextExpression, Constant(equivalencyExpression));
101103

102104
var notNull = NotEqual(destExpression, Constant(null));
103-
return Condition(notNull, map, Convert(nextMapperExpression, destExpression.Type));
105+
var collectionMapperExpression = _collectionMapper.MapExpression(configurationProvider, profileMap, memberMap, sourceExpression, destExpression, contextExpression);
106+
return Condition(notNull, map, Convert(collectionMapperExpression, destExpression.Type));
104107
}
105108
}
106109
}

0 commit comments

Comments
 (0)