@@ -90,12 +90,21 @@ protected override Expression VisitMember(MemberExpression node)
9090 return ex ;
9191 }
9292 fullName = BuildFullName ( propertyMapInfoList ) ;
93- var me = ExpressionFactory . MemberAccesses ( fullName , InfoDictionary [ parameterExpression ] . NewParameter ) ;
93+ var me = ExpressionHelpers . MemberAccesses ( fullName , InfoDictionary [ parameterExpression ] . NewParameter ) ;
9494
9595 this . TypeMappings . AddTypeMapping ( ConfigurationProvider , node . Type , me . Type ) ;
9696 return me ;
9797 }
9898
99+ protected override Expression VisitLambda < T > ( Expression < T > node )
100+ {
101+ var ex = this . Visit ( node . Body ) ;
102+
103+ var mapped = Expression . Lambda ( ex , node . GetDestinationParameterExpressions ( this . InfoDictionary , this . TypeMappings ) ) ;
104+ this . TypeMappings . AddTypeMapping ( ConfigurationProvider , node . Type , mapped . Type ) ;
105+ return mapped ;
106+ }
107+
99108 protected override Expression VisitUnary ( UnaryExpression node )
100109 {
101110 switch ( node . NodeType )
@@ -109,6 +118,13 @@ protected override Expression VisitUnary(UnaryExpression node)
109118 default :
110119 return base . VisitUnary ( node ) ;
111120 }
121+ case ExpressionType . Lambda :
122+ var lambdaExpression = ( LambdaExpression ) node . Operand ;
123+ var ex = this . Visit ( lambdaExpression . Body ) ;
124+
125+ var mapped = Expression . Quote ( Expression . Lambda ( ex , lambdaExpression . GetDestinationParameterExpressions ( this . InfoDictionary , this . TypeMappings ) ) ) ;
126+ this . TypeMappings . AddTypeMapping ( ConfigurationProvider , node . Type , mapped . Type ) ;
127+ return mapped ;
112128 default :
113129 return base . VisitUnary ( node ) ;
114130 }
@@ -137,7 +153,9 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
137153
138154 var listOfArgumentsForNewMethod = node . Arguments . Aggregate ( new List < Expression > ( ) , ( lst , next ) =>
139155 {
140- var mappedNext = ArgumentMapper . Create ( this , next ) . MappedArgumentExpression ;
156+ //var mappedNext = ArgumentMapper.Create(this, next).MappedArgumentExpression;
157+ //Using VisitUnary and VisitLambda instead of ArgumentMappers
158+ var mappedNext = this . Visit ( next ) ;
141159 TypeMappings . AddTypeMapping ( ConfigurationProvider , next . Type , mappedNext . Type ) ;
142160
143161 lst . Add ( mappedNext ) ;
@@ -151,9 +169,14 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
151169
152170 ConvertTypesIfNecessary ( node . Method . GetParameters ( ) , listOfArgumentsForNewMethod , node . Method ) ;
153171
172+ /*Using VisitUnary and VisitLambda instead of ArgumentMappers
173+ * return node.Method.IsStatic
174+ ? GetStaticExpression()
175+ : GetInstanceExpression(ArgumentMapper.Create(this, node.Object).MappedArgumentExpression);*/
176+
154177 return node . Method . IsStatic
155178 ? GetStaticExpression ( )
156- : GetInstanceExpression ( ArgumentMapper . Create ( this , node . Object ) . MappedArgumentExpression ) ;
179+ : GetInstanceExpression ( this . Visit ( node . Object ) ) ;
157180
158181 MethodCallExpression GetInstanceExpression ( Expression instance )
159182 => node . Method . IsGenericMethod
@@ -225,15 +248,18 @@ private static void AddPropertyMapInfo(Type parentType, string name, List<Proper
225248 }
226249 }
227250
251+ private bool GenericTypeDefinitionsAreEquivalent ( Type typeSource , Type typeDestination )
252+ => typeSource . IsGenericType ( ) && typeDestination . IsGenericType ( ) && typeSource . GetGenericTypeDefinition ( ) == typeDestination . GetGenericTypeDefinition ( ) ;
253+
228254 protected void FindDestinationFullName ( Type typeSource , Type typeDestination , string sourceFullName , List < PropertyMapInfo > propertyMapInfoList )
229255 {
230256 const string period = "." ;
257+
231258 if ( typeSource == typeDestination )
232259 {
233260 var sourceFullNameArray = sourceFullName . Split ( new [ ] { period [ 0 ] } , StringSplitOptions . RemoveEmptyEntries ) ;
234261 sourceFullNameArray . Aggregate ( propertyMapInfoList , ( list , next ) =>
235262 {
236-
237263 if ( list . Count == 0 )
238264 {
239265 AddPropertyMapInfo ( typeSource , next , list ) ;
@@ -250,6 +276,36 @@ protected void FindDestinationFullName(Type typeSource, Type typeDestination, st
250276 return ;
251277 }
252278
279+ if ( GenericTypeDefinitionsAreEquivalent ( typeSource , typeDestination ) )
280+ {
281+ if ( sourceFullName . IndexOf ( period , StringComparison . OrdinalIgnoreCase ) < 0 )
282+ {
283+ //sourceFullName is a member of the generic type definition so just add the members PropertyMapInfo
284+ AddPropertyMapInfo ( typeDestination , sourceFullName , propertyMapInfoList ) ;
285+ var sourceType = typeSource . GetFieldOrProperty ( sourceFullName ) . GetMemberType ( ) ;
286+ var destType = typeDestination . GetFieldOrProperty ( sourceFullName ) . GetMemberType ( ) ;
287+
288+ TypeMappings . AddTypeMapping ( ConfigurationProvider , sourceType , destType ) ;
289+
290+ return ;
291+ }
292+ else
293+ {
294+ //propertyName is a member of the generic type definition so just add the members PropertyMapInfo
295+ var propertyName = sourceFullName . Substring ( 0 , sourceFullName . IndexOf ( period , StringComparison . OrdinalIgnoreCase ) ) ;
296+ AddPropertyMapInfo ( typeDestination , propertyName , propertyMapInfoList ) ;
297+
298+ var sourceType = typeSource . GetFieldOrProperty ( propertyName ) . GetMemberType ( ) ;
299+ var destType = typeDestination . GetFieldOrProperty ( propertyName ) . GetMemberType ( ) ;
300+
301+ TypeMappings . AddTypeMapping ( ConfigurationProvider , sourceType , destType ) ;
302+
303+ var childFullName = sourceFullName . Substring ( sourceFullName . IndexOf ( period , StringComparison . OrdinalIgnoreCase ) + 1 ) ;
304+ FindDestinationFullName ( sourceType , destType , childFullName , propertyMapInfoList ) ;
305+ return ;
306+ }
307+ }
308+
253309 var typeMap = ConfigurationProvider . CheckIfMapExists ( sourceType : typeDestination , destinationType : typeSource ) ; //The destination becomes the source because to map a source expression to a destination expression,
254310 //we need the expressions used to create the source from the destination
255311
0 commit comments