1+ using System . Collections . Generic ;
2+ using System . Collections . ObjectModel ;
3+ using System . Linq ;
4+ using System . Linq . Expressions ;
5+ using AutoMapper . Configuration ;
6+ using AutoMapper . Internal ;
7+ using AutoMapper . Mappers . Internal ;
8+
9+ namespace AutoMapper . Mappers
10+ {
11+ using static Expression ;
12+ using static ExpressionFactory ;
13+ using static CollectionMapperExpressionFactory ;
14+
15+ public class ReadOnlyDictionaryMapper : IObjectMapper
16+ {
17+ public bool IsMatch ( TypePair context )
18+ {
19+ if ( ! ( context . SourceType . IsEnumerableType ( ) && context . DestinationType . IsGenericType ( ) ) )
20+ return false ;
21+
22+ var genericType = context . DestinationType . GetGenericTypeDefinition ( ) ;
23+
24+ return genericType == typeof ( ReadOnlyDictionary < , > ) || genericType == typeof ( IReadOnlyDictionary < , > ) ;
25+ }
26+
27+ public Expression MapExpression ( IConfigurationProvider configurationProvider , ProfileMap profileMap ,
28+ IMemberMap memberMap , Expression sourceExpression , Expression destExpression , Expression contextExpression )
29+ {
30+ var dictionaryTypes = ElementTypeHelper . GetElementTypes ( destExpression . Type , ElementTypeFlags . BreakKeyValuePair ) ;
31+ var dictType = typeof ( Dictionary < , > ) . MakeGenericType ( dictionaryTypes ) ;
32+ var dict = MapCollectionExpression ( configurationProvider , profileMap , memberMap , sourceExpression , Default ( dictType ) , contextExpression , typeof ( Dictionary < , > ) , MapKeyPairValueExpr ) ;
33+ var dest = Variable ( dictType , "dest" ) ;
34+
35+ var readOnlyDictType = destExpression . Type . IsInterface
36+ ? typeof ( ReadOnlyDictionary < , > ) . MakeGenericType ( dictionaryTypes )
37+ : destExpression . Type ;
38+
39+ var ctor = readOnlyDictType . GetDeclaredConstructors ( )
40+ . First ( ci => ci . GetParameters ( ) . Length == 1 && ci . GetParameters ( ) [ 0 ] . ParameterType . IsAssignableFrom ( dest . Type ) ) ;
41+
42+ return Block ( new [ ] { dest } ,
43+ Assign ( dest , dict ) ,
44+ Condition ( NotEqual ( dest , Default ( dictType ) ) ,
45+ ToType ( New ( ctor , dest ) , destExpression . Type ) ,
46+ Default ( destExpression . Type ) ) ) ;
47+ }
48+ }
49+ }
0 commit comments