@@ -11,15 +11,17 @@ namespace AutoMapper.EquivalencyExpression
1111{
1212 public static class EquivalentExpressions
1313 {
14- private static readonly
15- ConcurrentDictionary < IConfigurationProvider , ConcurrentDictionary < TypePair , IEquivalentComparer > >
16- EquivalentExpressionDictionary =
17- new ConcurrentDictionary < IConfigurationProvider , ConcurrentDictionary < TypePair , IEquivalentComparer > > ( ) ;
14+ private static readonly ConcurrentDictionary < IConfigurationProvider , ConcurrentDictionary < TypePair , IEquivalentComparer > >
15+ _equivalentExpressionDictionary = new ConcurrentDictionary < IConfigurationProvider , ConcurrentDictionary < TypePair , IEquivalentComparer > > ( ) ;
1816
19- private static ConcurrentDictionary < TypePair , IEquivalentComparer > _equalityComparisonCache = new ConcurrentDictionary < TypePair , IEquivalentComparer > ( ) ;
17+ private static readonly ConcurrentDictionary < IConfigurationProvider , IList < IGeneratePropertyMaps > >
18+ _generatePropertyMapsDictionary = new ConcurrentDictionary < IConfigurationProvider , IList < IGeneratePropertyMaps > > ( ) ;
2019
21- private static readonly ConcurrentDictionary < IConfigurationProvider , IList < IGeneratePropertyMaps > > GeneratePropertyMapsDictionary = new ConcurrentDictionary < IConfigurationProvider , IList < IGeneratePropertyMaps > > ( ) ;
22- private static IList < IGeneratePropertyMaps > _generatePropertyMapsCache = new List < IGeneratePropertyMaps > ( ) ;
20+ private static ConcurrentDictionary < TypePair , IEquivalentComparer >
21+ _equalityComparisonCache = new ConcurrentDictionary < TypePair , IEquivalentComparer > ( ) ;
22+
23+ private static IList < Func < Func < Type , object > , IGeneratePropertyMaps > >
24+ _generatePropertyMapsCache = new List < Func < Func < Type , object > , IGeneratePropertyMaps > > ( ) ;
2325
2426 public static void AddCollectionMappers ( this IMapperConfigurationExpression cfg )
2527 {
@@ -35,17 +37,24 @@ private static void InsertBefore<TObjectMapper>(this IMapperConfigurationExpress
3537 var targetMapper = mappers . FirstOrDefault ( om => om is TObjectMapper ) ;
3638 var index = targetMapper == null ? 0 : mappers . IndexOf ( targetMapper ) ;
3739 foreach ( var mapper in adds . Reverse ( ) )
40+ {
3841 mappers . Insert ( index , mapper ) ;
42+ }
43+
3944 cfg . Advanced . BeforeSeal ( c =>
4045 {
4146 foreach ( var configurationObjectMapper in adds )
47+ {
4248 configurationObjectMapper . ConfigurationProvider = c ;
49+ }
4350
44- EquivalentExpressionDictionary . AddOrUpdate ( c , _equalityComparisonCache , ( type , old ) => _equalityComparisonCache ) ;
51+ var propertyMapsGenerators = _generatePropertyMapsCache . Select ( x => x ? . Invoke ( c . ServiceCtor ) ) . ToList ( ) ;
52+
53+ _equivalentExpressionDictionary . AddOrUpdate ( c , _equalityComparisonCache , ( _ , __ ) => _equalityComparisonCache ) ;
4554 _equalityComparisonCache = new ConcurrentDictionary < TypePair , IEquivalentComparer > ( ) ;
4655
47- GeneratePropertyMapsDictionary . AddOrUpdate ( c , _generatePropertyMapsCache , ( type , old ) => _generatePropertyMapsCache ) ;
48- _generatePropertyMapsCache = new List < IGeneratePropertyMaps > ( ) ;
56+ _generatePropertyMapsDictionary . AddOrUpdate ( c , propertyMapsGenerators , ( _ , __ ) => propertyMapsGenerators ) ;
57+ _generatePropertyMapsCache = new List < Func < Func < Type , object > , IGeneratePropertyMaps > > ( ) ;
4958 } ) ;
5059 }
5160
@@ -80,9 +89,10 @@ internal static IEquivalentComparer GetEquivalentExpression(this IConfigurationO
8089
8190 internal static IEquivalentComparer GetEquivalentExpression ( IConfigurationProvider configurationProvider , TypeMap typeMap )
8291 {
83- return EquivalentExpressionDictionary [ configurationProvider ] . GetOrAdd ( typeMap . Types ,
84- tp =>
85- GeneratePropertyMapsDictionary [ configurationProvider ] . Select ( _ => _ . GeneratePropertyMaps ( typeMap ) . CreateEquivalentExpression ( ) ) . FirstOrDefault ( _ => _ != null ) ) ;
92+ return _equivalentExpressionDictionary [ configurationProvider ] . GetOrAdd ( typeMap . Types , _
93+ => _generatePropertyMapsDictionary [ configurationProvider ]
94+ . Select ( x => x . GeneratePropertyMaps ( typeMap ) . CreateEquivalentExpression ( ) )
95+ . FirstOrDefault ( x => x != null ) ) ;
8696 }
8797
8898 /// <summary>
@@ -98,42 +108,49 @@ public static IMappingExpression<TSource, TDestination> EqualityComparison<TSour
98108 where TDestination : class
99109 {
100110 var typePair = new TypePair ( typeof ( TSource ) , typeof ( TDestination ) ) ;
111+
101112 _equalityComparisonCache . AddOrUpdate ( typePair ,
102113 new EquivalentExpression < TSource , TDestination > ( EquivalentExpression ) ,
103- ( type , old ) => new EquivalentExpression < TSource , TDestination > ( EquivalentExpression ) ) ;
114+ ( _ , __ ) => new EquivalentExpression < TSource , TDestination > ( EquivalentExpression ) ) ;
115+
104116 return mappingExpression ;
105117 }
106118
107119 public static void SetGeneratePropertyMaps < TGeneratePropertyMaps > ( this IMapperConfigurationExpression cfg )
108- where TGeneratePropertyMaps : IGeneratePropertyMaps , new ( )
120+ where TGeneratePropertyMaps : IGeneratePropertyMaps
109121 {
110- cfg . SetGeneratePropertyMaps ( new TGeneratePropertyMaps ( ) ) ;
122+ _generatePropertyMapsCache . Add ( serviceCtor => ( IGeneratePropertyMaps ) serviceCtor ( typeof ( TGeneratePropertyMaps ) ) ) ;
111123 }
112124
113125 public static void SetGeneratePropertyMaps ( this IMapperConfigurationExpression cfg , IGeneratePropertyMaps generatePropertyMaps )
114126 {
115- _generatePropertyMapsCache . Add ( generatePropertyMaps ) ;
127+ _generatePropertyMapsCache . Add ( _ => generatePropertyMaps ) ;
116128 }
117129
118130 private static IEquivalentComparer CreateEquivalentExpression ( this IEnumerable < PropertyMap > propertyMaps )
119131 {
120132 if ( ! propertyMaps . Any ( ) || propertyMaps . Any ( pm => pm . DestinationProperty . GetMemberType ( ) != pm . SourceMember . GetMemberType ( ) ) )
133+ {
121134 return null ;
135+ }
136+
122137 var typeMap = propertyMaps . First ( ) . TypeMap ;
123138 var srcType = typeMap . SourceType ;
124139 var destType = typeMap . DestinationType ;
125140 var srcExpr = Expression . Parameter ( srcType , "src" ) ;
126141 var destExpr = Expression . Parameter ( destType , "dest" ) ;
127142
128143 var equalExpr = propertyMaps . Select ( pm => SourceEqualsDestinationExpression ( pm , srcExpr , destExpr ) ) . ToList ( ) ;
129- if ( ! equalExpr . Any ( ) )
144+ if ( equalExpr . Count == 0 )
145+ {
130146 return EquivalentExpression . BadValue ;
131- var finalExpression = equalExpr . Skip ( 1 ) . Aggregate ( equalExpr . First ( ) , Expression . And ) ;
147+ }
148+
149+ var finalExpression = equalExpr . Skip ( 1 ) . Aggregate ( equalExpr [ 0 ] , Expression . And ) ;
132150
133151 var expr = Expression . Lambda ( finalExpression , srcExpr , destExpr ) ;
134152 var genericExpressionType = typeof ( EquivalentExpression < , > ) . MakeGenericType ( srcType , destType ) ;
135- var equivilientExpression = Activator . CreateInstance ( genericExpressionType , expr ) as IEquivalentComparer ;
136- return equivilientExpression ;
153+ return Activator . CreateInstance ( genericExpressionType , expr ) as IEquivalentComparer ;
137154 }
138155
139156 private static BinaryExpression SourceEqualsDestinationExpression ( PropertyMap propertyMap , Expression srcExpr , Expression destExpr )
0 commit comments