private static Expression <UntypedMapperFunc> Wrap(MapRequest mapRequest, LambdaExpression typedExpression) { var sourceParameter = Expression.Parameter(typeof(object), "source"); var destinationParameter = Expression.Parameter(typeof(object), "destination"); var contextParameter = Expression.Parameter(typeof(ResolutionContext), "context"); var requestedSourceType = mapRequest.RequestedTypes.SourceType; var requestedDestinationType = mapRequest.RequestedTypes.DestinationType; var destination = requestedDestinationType.IsValueType() ? Expression.Coalesce(destinationParameter, Expression.New(requestedDestinationType)) : (Expression)destinationParameter; // Invoking a delegate here return(Expression.Lambda <UntypedMapperFunc>( ExpressionExtensions.ToType( Expression.Invoke(typedExpression, ExpressionExtensions.ToType(sourceParameter, requestedSourceType), ExpressionExtensions.ToType(destination, requestedDestinationType), contextParameter) , typeof(object)), sourceParameter, destinationParameter, contextParameter)); }
private static LambdaExpression GenerateObjectMapperExpression(MapRequest mapRequest, IObjectMapper mapperToUse, MapperConfiguration mapperConfiguration) { var destinationType = mapRequest.RequestedTypes.DestinationType; var source = Expression.Parameter(mapRequest.RequestedTypes.SourceType, "source"); var destination = Expression.Parameter(destinationType, "mapperDestination"); var context = Expression.Parameter(typeof(ResolutionContext), "context"); LambdaExpression fullExpression; if (mapperToUse == null) { var message = Expression.Constant("Missing type map configuration or unsupported mapping."); fullExpression = Expression.Lambda(Expression.Block(Expression.Throw(Expression.New(ExceptionConstructor, message, Expression.Constant(null, typeof(Exception)), Expression.Constant(mapRequest.RequestedTypes))), Expression.Default(destinationType)), source, destination, context); } else { var map = mapperToUse.MapExpression(mapperConfiguration.TypeMapRegistry, mapperConfiguration, null, ExpressionExtensions.ToType(source, mapRequest.RuntimeTypes.SourceType), destination, context); var mapToDestination = Expression.Lambda(ExpressionExtensions.ToType(map, destinationType), source, destination, context); fullExpression = TryCatch(mapToDestination, source, destination, context, mapRequest.RequestedTypes); } return(fullExpression); }
private static LambdaExpression GenerateTypeMapExpression(MapRequest mapRequest, TypeMap typeMap) { var mapExpression = typeMap.MapExpression; var typeMapSourceParameter = mapExpression.Parameters[0]; var typeMapDestinationParameter = mapExpression.Parameters[1]; var requestedSourceType = mapRequest.RequestedTypes.SourceType; var requestedDestinationType = mapRequest.RequestedTypes.DestinationType; if (typeMapSourceParameter.Type != requestedSourceType || typeMapDestinationParameter.Type != requestedDestinationType) { var requestedSourceParameter = Expression.Parameter(requestedSourceType, "source"); var requestedDestinationParameter = Expression.Parameter(requestedDestinationType, "typeMapDestination"); var contextParameter = Expression.Parameter(typeof(ResolutionContext), "context"); mapExpression = Expression.Lambda(ExpressionExtensions.ToType(Expression.Invoke(typeMap.MapExpression, ExpressionExtensions.ToType(requestedSourceParameter, typeMapSourceParameter.Type), ExpressionExtensions.ToType(requestedDestinationParameter, typeMapDestinationParameter.Type), contextParameter ), mapRequest.RuntimeTypes.DestinationType), requestedSourceParameter, requestedDestinationParameter, contextParameter); } return(mapExpression); }