Exemple #1
0
        private Expression CreateMapExpressionCore(ExpressionRequest request, Expression instanceParameter, TypePairCount typePairCount, TypeMap typeMap, LetPropertyMaps letPropertyMaps)
        {
            var bindings = new List <MemberBinding>();
            var depth    = GetDepth(request, typePairCount);

            if (typeMap.MaxDepth > 0 && depth >= typeMap.MaxDepth)
            {
                if (typeMap.Profile.AllowNullDestinationValues)
                {
                    return(null);
                }
            }
            else
            {
                bindings = CreateMemberBindings(request, typeMap, instanceParameter, typePairCount, letPropertyMaps);
            }
            Expression constructorExpression = DestinationConstructorExpression(typeMap, instanceParameter);

            if (instanceParameter is ParameterExpression)
            {
                constructorExpression = ((LambdaExpression)constructorExpression).ReplaceParameters(instanceParameter);
            }
            var visitor = new NewFinderVisitor();

            visitor.Visit(constructorExpression);

            var expression = MemberInit(
                visitor.NewExpression,
                bindings.ToArray()
                );

            return(expression);
        }
        internal static Expression CreateMapExpression(IMappingEngine mappingEngine, ExpressionRequest request, Expression instanceParameter, Internal.IDictionary <ExpressionRequest, int> typePairCount)
        {
            var typeMap = mappingEngine.ConfigurationProvider.FindTypeMapFor(request.SourceType,
                                                                             request.DestinationType);

            if (typeMap == null)
            {
                const string MessageFormat = "Missing map from {0} to {1}. Create using Mapper.CreateMap<{0}, {1}>.";

                var message = string.Format(MessageFormat, request.SourceType.Name, request.DestinationType.Name);

                throw new InvalidOperationException(message);
            }

            var bindings = CreateMemberBindings(mappingEngine, request, typeMap, instanceParameter, typePairCount);

            var parameterReplacer = new ParameterReplacementVisitor(instanceParameter);
            var visitor           = new NewFinderVisitor();
            var ctorExpr          = typeMap.ConstructExpression ?? Expression.Lambda(Expression.New(request.DestinationType));

            visitor.Visit(parameterReplacer.Visit(ctorExpr));

            var expression = Expression.MemberInit(
                visitor.NewExpression,
                bindings.ToArray()
                );

            return(expression);
        }
        public Expression CreateMapExpression(ExpressionRequest request,
                                              Expression instanceParameter, ConcurrentDictionary <ExpressionRequest, int> typePairCount)
        {
            var typeMap = ConfigurationProvider.ResolveTypeMap(request.SourceType,
                                                               request.DestinationType);

            if (typeMap == null)
            {
                const string MessageFormat = "Missing map from {0} to {1}. Create using Mapper.CreateMap<{0}, {1}>.";

                var message = string.Format(MessageFormat, request.SourceType.Name, request.DestinationType.Name);

                throw new InvalidOperationException(message);
            }

            var parameterReplacer = instanceParameter is ParameterExpression ? new ParameterReplacementVisitor(instanceParameter) : null;
            var customProjection  = typeMap.CustomProjection;

            if (customProjection != null)
            {
                return(parameterReplacer == null ? customProjection.Body : parameterReplacer.Visit(customProjection.Body));
            }

            var bindings   = new List <MemberBinding>();
            var visitCount = typePairCount.AddOrUpdate(request, 0, (tp, i) => i + 1);

            if (visitCount >= typeMap.MaxDepth)
            {
                if (ConfigurationProvider.AllowNullDestinationValues)
                {
                    return(null);
                }
            }
            else
            {
                bindings = CreateMemberBindings(request, typeMap, instanceParameter, typePairCount);
            }
            Expression constructorExpression = typeMap.DestinationConstructorExpression(instanceParameter);

            if (parameterReplacer != null)
            {
                constructorExpression = parameterReplacer.Visit(constructorExpression);
            }
            var visitor = new NewFinderVisitor();

            visitor.Visit(constructorExpression);

            var expression = Expression.MemberInit(
                visitor.NewExpression,
                bindings.ToArray()
                );

            return(expression);
        }
        public Expression CreateMapExpression(ExpressionRequest request, Expression instanceParameter, IDictionary <ExpressionRequest, int> typePairCount)
        {
            var typeMap = _configurationProvider.ResolveTypeMap(request.SourceType,
                                                                request.DestinationType);

            if (typeMap == null)
            {
                throw QueryMapperHelper.MissingMapException(request.SourceType, request.DestinationType);
            }

            if (typeMap.CustomProjection != null)
            {
                return(typeMap.CustomProjection.ReplaceParameters(instanceParameter));
            }

            var bindings = new List <MemberBinding>();
            var depth    = GetDepth(request, typePairCount);

            if (typeMap.MaxDepth > 0 && depth >= typeMap.MaxDepth)
            {
                if (typeMap.Profile.AllowNullDestinationValues)
                {
                    return(null);
                }
            }
            else
            {
                bindings = CreateMemberBindings(request, typeMap, instanceParameter, typePairCount);
            }
            Expression constructorExpression = DestinationConstructorExpression(typeMap, instanceParameter);

            if (instanceParameter is ParameterExpression)
            {
                constructorExpression = ((LambdaExpression)constructorExpression).ReplaceParameters(instanceParameter);
            }
            var visitor = new NewFinderVisitor();

            visitor.Visit(constructorExpression);

            var expression = MemberInit(
                visitor.NewExpression,
                bindings.ToArray()
                );

            return(expression);
        }
        public Expression CreateMapExpression(ExpressionRequest request,
            Expression instanceParameter, Internal.IDictionary<ExpressionRequest, int> typePairCount)
        {
            var typeMap = ConfigurationProvider.ResolveTypeMap(request.SourceType,
                request.DestinationType);

            if (typeMap == null)
            {
                const string MessageFormat = "Missing map from {0} to {1}. Create using Mapper.CreateMap<{0}, {1}>.";

                var message = string.Format(MessageFormat, request.SourceType.Name, request.DestinationType.Name);

                throw new InvalidOperationException(message);
            }

            var bindings = CreateMemberBindings(request, typeMap, instanceParameter, typePairCount);

            var parameterReplacer = new ParameterReplacementVisitor(instanceParameter);
            var visitor = new NewFinderVisitor();
            var constructorExpression = typeMap.DestinationConstructorExpression(instanceParameter);
            visitor.Visit(parameterReplacer.Visit(constructorExpression));

            var expression = Expression.MemberInit(
                visitor.NewExpression,
                bindings.ToArray()
                );
            return expression;
        }
Exemple #6
0
        private Expression CreateMapExpressionCore(ExpressionRequest request, Expression instanceParameter, TypePairCount typePairCount, TypeMap typeMap, LetPropertyMaps letPropertyMaps)
        {
            var memberBindings = new List <MemberBinding>();
            var depth          = GetDepth(request, typePairCount);

            if (typeMap.MaxDepth > 0 && depth >= typeMap.MaxDepth)
            {
                if (typeMap.Profile.AllowNullDestinationValues)
                {
                    return(null);
                }
            }
            else
            {
                memberBindings = CreateMemberBindings();
            }
            Expression constructorExpression = DestinationConstructorExpression(typeMap, instanceParameter, letPropertyMaps);

            if (instanceParameter is ParameterExpression)
            {
                constructorExpression = ((LambdaExpression)constructorExpression).ReplaceParameters(instanceParameter);
            }
            var visitor = new NewFinderVisitor();

            visitor.Visit(constructorExpression);

            var expression = MemberInit(
                visitor.NewExpression,
                memberBindings.ToArray()
                );

            return(expression);

            List <MemberBinding> CreateMemberBindings()
            {
                var bindings = new List <MemberBinding>();

                foreach (var propertyMap in typeMap.PropertyMaps
                         .Where(pm => (!pm.ExplicitExpansion || request.MembersToExpand.Contains(pm.DestinationMember)) &&
                                pm.CanResolveValue && ReflectionHelper.CanBeSet(pm.DestinationMember))
                         .OrderBy(pm => pm.DestinationName))
                {
                    var propertyExpression = new PropertyExpression(propertyMap);
                    letPropertyMaps.Push(propertyExpression);

                    CreateMemberBinding(propertyExpression);

                    letPropertyMaps.Pop();
                }
                return(bindings);

                void CreateMemberBinding(PropertyExpression propertyExpression)
                {
                    var propertyMap = propertyExpression.PropertyMap;
                    var result      = ResolveExpression(propertyMap, request.SourceType, instanceParameter, letPropertyMaps);

                    propertyExpression.Expression = result.ResolutionExpression;
                    var propertyTypeMap = _configurationProvider.ResolveTypeMap(result.Type, propertyMap.DestinationType);
                    var propertyRequest = new ExpressionRequest(result.Type, propertyMap.DestinationType, request.MembersToExpand, request);

                    if (propertyRequest.AlreadyExists && depth >= _configurationProvider.RecursiveQueriesMaxDepth)
                    {
                        return;
                    }
                    var binder = _configurationProvider.Binders.FirstOrDefault(b => b.IsMatch(propertyMap, propertyTypeMap, result));

                    if (binder == null)
                    {
                        var message =
                            $"Unable to create a map expression from {propertyMap.SourceMember?.DeclaringType?.Name}.{propertyMap.SourceMember?.Name} ({result.Type}) to {propertyMap.DestinationMember.DeclaringType?.Name}.{propertyMap.DestinationName} ({propertyMap.DestinationType})";
                        throw new AutoMapperMappingException(message, null, typeMap.Types, typeMap, propertyMap);
                    }
                    var bindExpression = binder.Build(_configurationProvider, propertyMap, propertyTypeMap, propertyRequest, result, typePairCount, letPropertyMaps);

                    if (bindExpression == null)
                    {
                        return;
                    }
                    var rhs = propertyMap.ValueTransformers
                              .Concat(typeMap.ValueTransformers)
                              .Concat(typeMap.Profile.ValueTransformers)
                              .Where(vt => vt.IsMatch(propertyMap))
                              .Aggregate(bindExpression.Expression, (current, vtConfig) => ToType(ReplaceParameters(vtConfig.TransformerExpression, ToType(current, vtConfig.ValueType)), propertyMap.DestinationType));

                    bindExpression = bindExpression.Update(rhs);

                    bindings.Add(bindExpression);
                }
            }
        }