Example #1
0
        public object Map(ResolutionContext context, IMappingEngineRunner mapper)
        {
            var sourceDelegateType = context.SourceType.GetGenericArguments()[0];
            var destDelegateType   = context.DestinationType.GetGenericArguments()[0];
            var expression         = (LambdaExpression)context.SourceValue;

            if (sourceDelegateType.GetGenericTypeDefinition() != destDelegateType.GetGenericTypeDefinition())
            {
                throw new AutoMapperMappingException("Source and destination expressions must be of the same type.");
            }

            var destArgType = destDelegateType.GetGenericArguments()[0];

            if (destArgType.IsGenericType())
            {
                destArgType = destArgType.GetGenericArguments()[0];
            }
            var sourceArgType = sourceDelegateType.GetGenericArguments()[0];

            if (sourceArgType.IsGenericType())
            {
                sourceArgType = sourceArgType.GetGenericArguments()[0];
            }

            var typeMap = Mapper.FindTypeMapFor(destArgType, sourceArgType);

            var parentMasterVisitor = new MappingVisitor(destDelegateType.GetGenericArguments());
            var typeMapVisitor      = new MappingVisitor(typeMap, expression.Parameters[0], Expression.Parameter(destDelegateType.GetGenericArguments()[0], expression.Parameters[0].Name), parentMasterVisitor, destDelegateType.GetGenericArguments());

            // Map expression body and variable seperately
            var parameters = expression.Parameters.Select(typeMapVisitor.Visit).OfType <ParameterExpression>();
            var body       = typeMapVisitor.Visit(expression.Body);

            return(Expression.Lambda(body, parameters));
        }
        public object Map(ResolutionContext context, IMappingEngineRunner mapper)
        {
            var sourceDelegateType = context.SourceType.GetGenericArguments()[0];
            var destDelegateType = context.DestinationType.GetGenericArguments()[0];
            var expression = (LambdaExpression) context.SourceValue;

            if (sourceDelegateType.GetGenericTypeDefinition() != destDelegateType.GetGenericTypeDefinition())
                throw new AutoMapperMappingException("Source and destination expressions must be of the same type.");

            var parameters = expression.Parameters.ToArray();
            var body = expression.Body;

            for (int i = 0; i < expression.Parameters.Count; i++)
            {
                var sourceParamType = sourceDelegateType.GetGenericArguments()[i];
                var destParamType = destDelegateType.GetGenericArguments()[i];

                if (sourceParamType == destParamType)
                    continue;

                var typeMap = mapper.ConfigurationProvider.ResolveTypeMap(destParamType, sourceParamType);

                if (typeMap == null)
                    throw new AutoMapperMappingException(
                        $"Could not find type map from destination type {destParamType} to source type {sourceParamType}. Use CreateMap to create a map from the source to destination types.");

                var oldParam = expression.Parameters[i];
                var newParam = Expression.Parameter(typeMap.SourceType, oldParam.Name);
                parameters[i] = newParam;
                var visitor = new MappingVisitor(typeMap, oldParam, newParam);
                body = visitor.Visit(body);
            }
            return Expression.Lambda(body, parameters);
        }
Example #3
0
        public static TDestination Map<TSource, TDestination>(TSource expression, ResolutionContext context)
            where TSource : LambdaExpression
            where TDestination : LambdaExpression
        {
            var sourceDelegateType = typeof(TSource).GetTypeInfo().GenericTypeArguments[0];
            var destDelegateType = typeof(TDestination).GetTypeInfo().GenericTypeArguments[0];

            if (sourceDelegateType.GetGenericTypeDefinition() != destDelegateType.GetGenericTypeDefinition())
                throw new AutoMapperMappingException("Source and destination expressions must be of the same type.", null, new TypePair(typeof(TSource), typeof(TDestination)));

            var destArgType = destDelegateType.GetTypeInfo().GenericTypeArguments[0];
            if (destArgType.IsGenericType())
                destArgType = destArgType.GetTypeInfo().GenericTypeArguments[0];
            var sourceArgType = sourceDelegateType.GetTypeInfo().GenericTypeArguments[0];
            if (sourceArgType.IsGenericType())
                sourceArgType = sourceArgType.GetTypeInfo().GenericTypeArguments[0];

            var typeMap = context.ConfigurationProvider.ResolveTypeMap(destArgType, sourceArgType);

            var parentMasterVisitor = new MappingVisitor(context.ConfigurationProvider,
                destDelegateType.GetTypeInfo().GenericTypeArguments);
            var typeMapVisitor = new MappingVisitor(context.ConfigurationProvider, typeMap, expression.Parameters[0],
                Expression.Parameter(destDelegateType.GetTypeInfo().GenericTypeArguments[0], expression.Parameters[0].Name),
                parentMasterVisitor, destDelegateType.GetTypeInfo().GenericTypeArguments);

            // Map expression body and variable seperately
            var parameters = expression.Parameters.Select(typeMapVisitor.Visit).OfType<ParameterExpression>();
            var body = typeMapVisitor.Visit(expression.Body);
            return (TDestination)Expression.Lambda(body, parameters);
        }
Example #4
0
 internal MappingVisitor(IConfigurationProvider configurationProvider, TypeMap typeMap, Expression oldParam, Expression newParam, MappingVisitor parentMappingVisitor = null, IList<Type> destSubTypes = null)
 {
     _configurationProvider = configurationProvider;
     _typeMap = typeMap;
     _oldParam = oldParam;
     _newParam = newParam;
     _parentMappingVisitor = parentMappingVisitor;
     if(destSubTypes != null)
         _destSubTypes = destSubTypes;
 }
Example #5
0
 internal MappingVisitor(TypeMap typeMap, Expression oldParam, Expression newParam, MappingVisitor parentMappingVisitor = null, IList <Type> destSubTypes = null)
 {
     _typeMap              = typeMap;
     _oldParam             = oldParam;
     _newParam             = newParam;
     _parentMappingVisitor = parentMappingVisitor;
     if (destSubTypes != null)
     {
         _destSubTypes = destSubTypes;
     }
 }
            protected override Expression VisitBinary(BinaryExpression node)
            {
                var newLeft  = Visit(node.Left);
                var newRight = Visit(node.Right);

                if (newLeft.Type != newRight.Type)
                {
                    if (ReflectionHelper.CanImplicitConvert(newRight.Type, newLeft.Type))
                    {
                        newRight = ExpressionFactory.ToType(newRight, newLeft.Type);
                    }
                    else if (ReflectionHelper.CanImplicitConvert(newLeft.Type, newRight.Type))
                    {
                        newLeft = ExpressionFactory.ToType(newLeft, newRight.Type);
                    }
                    else
                    {
                        var typeMap = _configurationProvider.ResolveTypeMap(newRight.Type, newLeft.Type);
                        if (typeMap != null)
                        {
                            var visitor = new MappingVisitor(_configurationProvider, typeMap, newRight, newLeft, this);
                            newRight = visitor.Visit(newRight);
                        }
                        else
                        {
                            // check if the non-string expression is a null constent
                            // as this would lead to a "null.ToString()" and thus an error when executing the expression
                            if (newLeft.Type != newRight.Type && newRight.Type == typeof(string) && !IsNullConstant(newLeft))
                            {
                                newLeft = Call(newLeft, typeof(object).GetDeclaredMethod("ToString"));
                            }
                            if (newRight.Type != newLeft.Type && newLeft.Type == typeof(string) && !IsNullConstant(newRight))
                            {
                                newRight = Call(newRight, typeof(object).GetDeclaredMethod("ToString"));
                            }
                            CheckNullableToNonNullableChanges(node.Left, node.Right, ref newLeft, ref newRight);
                            CheckNullableToNonNullableChanges(node.Right, node.Left, ref newRight, ref newLeft);
                        }
                    }
                }

                switch (node.NodeType)
                {
                case ExpressionType.Add:
                    return(MakeBinary(node.NodeType, newLeft, newRight, node.IsLiftedToNull, node.Method));

                default:
                    return(MakeBinary(node.NodeType, newLeft, newRight));
                }

                bool IsNullConstant(Expression expression) => expression is ConstantExpression constant && constant.Value == null;
            }
Example #7
0
 private Expression GetConvertedSubMemberCall(MemberExpression node)
 {
     var baseExpression = Visit(node.Expression);
     var propertyMap = FindPropertyMapOfExpression(node.Expression as MemberExpression);
     if (propertyMap == null)
         return node;
     var sourceType = propertyMap.SourceMember.GetMemberType();
     var destType = propertyMap.DestinationPropertyType;
     if (sourceType == destType)
         return Expression.MakeMemberAccess(baseExpression, node.Member);
     var typeMap = _configurationProvider.FindTypeMapFor(sourceType, destType);
     var subVisitor = new MappingVisitor(_configurationProvider, typeMap, node.Expression, baseExpression, this);
     var newExpression = subVisitor.Visit(node);
     _destSubTypes = _destSubTypes.Concat(subVisitor._destSubTypes).ToArray();
     return newExpression;
 }
        public object Map(ResolutionContext context, IMappingEngineRunner mapper)
        {
            var sourceDelegateType = context.SourceType.GetGenericArguments()[0];
            var destDelegateType   = context.DestinationType.GetGenericArguments()[0];
            var expression         = (LambdaExpression)context.SourceValue;

            if (sourceDelegateType.GetGenericTypeDefinition() != destDelegateType.GetGenericTypeDefinition())
            {
                throw new AutoMapperMappingException("Source and destination expressions must be of the same type.");
            }

            var parameters = expression.Parameters.ToArray();
            var body       = expression.Body;

            for (int i = 0; i < expression.Parameters.Count; i++)
            {
                var sourceParamType = sourceDelegateType.GetGenericArguments()[i];
                var destParamType   = destDelegateType.GetGenericArguments()[i];

                if (sourceParamType == destParamType)
                {
                    continue;
                }

                var typeMap = mapper.ConfigurationProvider.FindTypeMapFor(destParamType, sourceParamType);

                if (typeMap == null)
                {
                    throw new AutoMapperMappingException(
                              string.Format(
                                  "Could not find type map from destination type {0} to source type {1}. Use CreateMap to create a map from the source to destination types.",
                                  destParamType, sourceParamType));
                }

                var oldParam = expression.Parameters[i];
                var newParam = Expression.Parameter(typeMap.SourceType, oldParam.Name);
                parameters[i] = newParam;
                var visitor = new MappingVisitor(typeMap, oldParam, newParam);
                body = visitor.Visit(body);
            }
            return(Expression.Lambda(body, parameters));
        }
        public Expression Map(Expression expression, Type sourceType, Type targetType)
        {
            Dictionary <string, IMappingAssociation> assocs;

            if (!_associations.TryGetValue(new TypeMapKey(sourceType, targetType), out assocs))
            {
                throw new InvalidOperationException(string.Format("Mapping from type {0} to type {1} is not configured", sourceType, targetType));
            }

            var ctx = new MapContext
            {
                From         = sourceType,
                To           = targetType,
                Associations = assocs
            };

            var visitor = new MappingVisitor(ctx, this);

            var morphed = visitor.Visit(expression);

            return(morphed);
        }
Example #10
0
            private Expression GetConvertedSubMemberCall(MemberExpression node)
            {
                var baseExpression = Visit(node.Expression);
                var propertyMap    = FindPropertyMapOfExpression(node.Expression as MemberExpression);

                if (propertyMap == null)
                {
                    return(node);
                }
                var sourceType = GetSourceType(propertyMap);
                var destType   = propertyMap.DestinationType;

                if (sourceType == destType)
                {
                    return(MakeMemberAccess(baseExpression, node.Member));
                }
                var typeMap       = _configurationProvider.Internal().ResolveTypeMap(sourceType, destType);
                var subVisitor    = new MappingVisitor(_configurationProvider, typeMap, node.Expression, baseExpression, this);
                var newExpression = subVisitor.Visit(node);

                _destSubTypes = _destSubTypes.Concat(subVisitor._destSubTypes).ToArray();
                return(newExpression);
            }
            private Expression GetConvertedArgument(Expression node)
            {
                var baseExpression = Visit(node);

                if (node.Type == baseExpression.Type)
                {
                    return(baseExpression);
                }

                var propertyMap = FindPropertyMapOfExpression(node as MemberExpression);

                if (propertyMap == null)
                {
                    return(ExpressionFactory.ToType(baseExpression, node.Type));
                }

                var sourceType = GetSourceType(propertyMap);
                var destType   = propertyMap.DestinationPropertyType;

                if (sourceType != destType)
                {
                    if (ReflectionHelper.CanImplicitConvert(sourceType, destType))
                    {
                        return(ExpressionFactory.ToType(baseExpression, destType));
                    }
                }

                var typeMap = _configurationProvider.ResolveTypeMap(sourceType, destType);

                if (typeMap != null)
                {
                    var visitor = new MappingVisitor(_configurationProvider, typeMap, baseExpression, node, this);
                    return(visitor.Visit(node));
                }
                return(baseExpression);
            }