1- using System . Collections . Generic ;
1+ using System . Collections . Concurrent ;
2+ using System . Collections . Generic ;
23using System . Linq ;
34using System . Linq . Expressions ;
45using 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