예제 #1
0
        public IActionResult EvaluateExpression([FromBody, SwaggerRequestBody("The request that contains the expression and variables")] ExpressionRequest request)
        {
            if (!this.ModelState.IsValid)
            {
                this.logger.LogError("This model doesn't look right to me!");
                throw new ArgumentException("Your request body wasn't proper! ");
            }

            this.logger.LogInformation($"All looks good.  Let's start parsing: {request.Expression}.");
            MathExpressionBuilder builder          = new MathExpressionBuilder(request.Expression);
            IMathExpression       parsedExpression = builder.GenerateExpression();

            this.logger.LogDebug("Yup.  Looks like a legit expression.");
            foreach (var variable in request.VariableEntries)
            {
                builder.SetVariable(variable.Name, variable.Value.ToString());
                this.logger.LogDebug("Setting variable {0} with {1}", variable.Name, variable.Value);
            }

            ExpressionResponse response = new ExpressionResponse
            {
                AdjustedExpression = parsedExpression.ToString(),
                Expression         = request.Expression,
                VariableEntries    = request.VariableEntries,
                ValueGenerated     = parsedExpression.EvaluateExpression()
            };

            return(this.Ok(response));
        }
        public async Task <ExpressionResponse> CalculateResult(string[] expressions, int?precision = 0)
        {
            try
            {
                HttpResponseMessage response = null;
                ExpressionRequest   reqBody  = new ExpressionRequest()
                {
                    expr = expressions, precision = precision.HasValue ? precision.Value : 0
                };
                var bodyJson = JsonConvert.SerializeObject(reqBody);

                response = await PostHttpRequest(bodyJson);

                if (response != null)
                {
                    response.EnsureSuccessStatusCode();
                    var responseResult     = response.Content.ReadAsStringAsync();
                    var calculatedResponse = JsonConvert.DeserializeObject <ExpressionResponse>(responseResult.Result.ToString());
                    return(calculatedResponse);
                }
                return(null);
            }
            catch (Exception ex)
            {
                return(new ExpressionResponse()
                {
                    result = null, error = $"Error occurred while calling API to evaluate expression - {ex.Message}"
                });
            }
        }
예제 #3
0
        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);
        }
        private static MemberAssignment BindEnumerableExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary <ExpressionRequest, int> typePairCount, LetPropertyMaps letPropertyMaps)
        {
            var destinationListType = ElementTypeHelper.GetElementType(propertyMap.DestinationType);
            var sourceListType      = ElementTypeHelper.GetElementType(propertyMap.SourceType);
            var expression          = result.ResolutionExpression;

            if (sourceListType != destinationListType)
            {
                var listTypePair           = new ExpressionRequest(sourceListType, destinationListType, request.MembersToExpand, request);
                var transformedExpressions = configuration.ExpressionBuilder.CreateMapExpression(listTypePair, typePairCount, letPropertyMaps.New());
                if (transformedExpressions == null)
                {
                    return(null);
                }
                expression = transformedExpressions.Aggregate(expression, Select);
            }

            expression =
                propertyMap.DestinationType.IsArray
                    ? Expression.Call(typeof(Enumerable), nameof(Enumerable.ToArray), new[] { destinationListType }, expression)
                    : propertyMap.DestinationType.IsCollectionType()
                        ? Expression.Call(typeof(Enumerable), nameof(Enumerable.ToList), new[] { destinationListType }, expression)
                        : expression;

            return(Expression.Bind(propertyMap.DestinationMember, expression));
        }
        private static MemberAssignment BindEnumerableExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary<ExpressionRequest, int> typePairCount)
        {
            var destinationListType = TypeHelper.GetElementType(propertyMap.DestinationPropertyType);
            var sourceListType = TypeHelper.GetElementType(propertyMap.SourceType);
            var expression = result.ResolutionExpression;

            if (sourceListType != destinationListType)
            {
                var listTypePair = new ExpressionRequest(sourceListType, destinationListType, request.MembersToExpand);
                var transformedExpression = configuration.ExpressionBuilder.CreateMapExpression(listTypePair, typePairCount);
                if(transformedExpression == null)
                {
                    return null;
                }
                expression = Expression.Call(typeof (Enumerable), "Select", new[] {sourceListType, destinationListType}, result.ResolutionExpression, transformedExpression);
            }

            expression = Expression.Call(typeof(Enumerable), propertyMap.DestinationPropertyType.IsArray ? "ToArray" : "ToList", new[] { destinationListType }, expression);

            if(configuration.Configuration.AllowNullCollections) {
                expression = Expression.Condition(
                            Expression.NotEqual(
                                Expression.TypeAs(result.ResolutionExpression, typeof(object)),
                                Expression.Constant(null)),
                            expression,
                            Expression.Constant(null, propertyMap.DestinationPropertyType));
            }

            return Expression.Bind(propertyMap.DestinationProperty, expression);
        }
        private static MemberAssignment BindEnumerableExpression(IMappingEngine mappingEngine, PropertyMap propertyMap,
            ExpressionRequest request, ExpressionResolutionResult result,
            Internal.IDictionary<ExpressionRequest, int> typePairCount)
        {
            MemberAssignment bindExpression;
            Type destinationListType = GetDestinationListTypeFor(propertyMap);
            Type sourceListType = null;
            // is list

            if (result.Type.IsArray)
            {
                sourceListType = result.Type.GetElementType();
            }
            else
            {
                sourceListType = result.Type.GetGenericArguments().First();
            }
            var listTypePair = new ExpressionRequest(sourceListType, destinationListType, request.IncludedMembers);

            var selectExpression = result.ResolutionExpression;
            if (sourceListType != destinationListType)
            {
                var transformedExpression = Extensions.CreateMapExpression(mappingEngine, listTypePair, typePairCount);
                selectExpression = Expression.Call(
                    typeof (Enumerable),
                    "Select",
                    new[] {sourceListType, destinationListType},
                    result.ResolutionExpression,
                    transformedExpression);
            }

            if (typeof (IList<>).MakeGenericType(destinationListType)
                .IsAssignableFrom(propertyMap.DestinationPropertyType)
                ||
                typeof (ICollection<>).MakeGenericType(destinationListType)
                    .IsAssignableFrom(propertyMap.DestinationPropertyType))
            {
                // Call .ToList() on IEnumerable
                var toListCallExpression = GetToListCallExpression(propertyMap, destinationListType, selectExpression);

                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, toListCallExpression);
            }
            else if (propertyMap.DestinationPropertyType.IsArray)
            {
                // Call .ToArray() on IEnumerable
                MethodCallExpression toArrayCallExpression = Expression.Call(
                    typeof (Enumerable),
                    "ToArray",
                    new[] {destinationListType},
                    selectExpression);
                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, toArrayCallExpression);
            }
            else
            {
                // destination type implements ienumerable, but is not an ilist. allow deferred enumeration
                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, selectExpression);
            }
            return bindExpression;
        }
예제 #7
0
        public LambdaExpression CreateMapExpression(ExpressionRequest request, ConcurrentDictionary <ExpressionRequest, int> typePairCount)
        {
            // this is the input parameter of this expression with name <variableName>
            var instanceParameter = Expression.Parameter(request.SourceType, "dto");
            var total             = CreateMapExpression(request, instanceParameter, typePairCount);
            var delegateType      = typeof(Func <,>).MakeGenericType(request.SourceType, request.DestinationType);

            return(Expression.Lambda(delegateType, total, instanceParameter));
        }
예제 #8
0
        private static MemberAssignment BindEnumerableExpression(IMappingEngine mappingEngine, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, Internal.IDictionary <ExpressionRequest, int> typePairCount)
        {
            MemberAssignment bindExpression;
            Type             destinationListType = GetDestinationListTypeFor(propertyMap);
            Type             sourceListType      = null;

            // is list

            if (result.Type.IsArray)
            {
                sourceListType = result.Type.GetElementType();
            }
            else
            {
                sourceListType = result.Type.GetGenericArguments().First();
            }
            var listTypePair = new ExpressionRequest(sourceListType, destinationListType, request.IncludedMembers);


            var selectExpression = result.ResolutionExpression;

            if (sourceListType != destinationListType)
            {
                var transformedExpression = Extensions.CreateMapExpression(mappingEngine, listTypePair, typePairCount);
                selectExpression = Expression.Call(
                    typeof(Enumerable),
                    "Select",
                    new[] { sourceListType, destinationListType },
                    result.ResolutionExpression,
                    transformedExpression);
            }

            if (typeof(IList <>).MakeGenericType(destinationListType).IsAssignableFrom(propertyMap.DestinationPropertyType) ||
                typeof(ICollection <>).MakeGenericType(destinationListType).IsAssignableFrom(propertyMap.DestinationPropertyType))
            {
                // Call .ToList() on IEnumerable
                var toListCallExpression = GetToListCallExpression(propertyMap, destinationListType, selectExpression);

                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, toListCallExpression);
            }
            else if (propertyMap.DestinationPropertyType.IsArray)
            {
                // Call .ToArray() on IEnumerable
                MethodCallExpression toArrayCallExpression = Expression.Call(
                    typeof(Enumerable),
                    "ToArray",
                    new Type[] { destinationListType },
                    selectExpression);
                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, toArrayCallExpression);
            }
            else
            {
                // destination type implements ienumerable, but is not an ilist. allow deferred enumeration
                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, selectExpression);
            }
            return(bindExpression);
        }
예제 #9
0
        public LambdaExpression CreateMapExpression(ExpressionRequest request, Internal.IDictionary <ExpressionRequest, int> typePairCount)
        {
            // this is the input parameter of this expression with name <variableName>
            ParameterExpression instanceParameter = Expression.Parameter(request.SourceType, "dto");

            var total = CreateMapExpression(request, instanceParameter, typePairCount);

            return(Expression.Lambda(total, instanceParameter));
        }
        private static MemberAssignment BindEnumerableExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary <ExpressionRequest, int> typePairCount)
        {
            var destinationListType = GetDestinationListTypeFor(propertyMap);

            var sourceListType = result.Type.IsArray ? result.Type.GetElementType() : result.Type.GetTypeInfo().GenericTypeArguments.First();
            var listTypePair   = new ExpressionRequest(sourceListType, destinationListType, request.MembersToExpand);

            Expression exp = result.ResolutionExpression;

            if (sourceListType != destinationListType)
            {
                var transformedExpression = configuration.ExpressionBuilder.CreateMapExpression(listTypePair, typePairCount);
                if (transformedExpression == null)
                {
                    return(null);
                }
                exp = Expression.Call(
                    typeof(Enumerable),
                    "Select",
                    new[] { sourceListType, destinationListType },
                    result.ResolutionExpression,
                    transformedExpression);
            }


            if (typeof(IList <>).MakeGenericType(destinationListType)
                .GetTypeInfo().IsAssignableFrom(propertyMap.DestinationPropertyType.GetTypeInfo())
                ||
                typeof(ICollection <>).MakeGenericType(destinationListType)
                .GetTypeInfo().IsAssignableFrom(propertyMap.DestinationPropertyType.GetTypeInfo()))
            {
                // Call .ToList() on IEnumerable
                exp = GetToListCallExpression(propertyMap, destinationListType, exp);
            }
            else if (propertyMap.DestinationPropertyType.IsArray)
            {
                // Call .ToArray() on IEnumerable
                exp = Expression.Call(
                    typeof(Enumerable),
                    "ToArray",
                    new[] { destinationListType },
                    exp);
            }

            if (configuration.AllowNullCollections)
            {
                exp = Expression.Condition(
                    Expression.NotEqual(
                        Expression.TypeAs(result.ResolutionExpression, typeof(object)),
                        Expression.Constant(null)),
                    exp,
                    Expression.Constant(null, propertyMap.DestinationPropertyType));
            }

            return(Expression.Bind(propertyMap.DestinationProperty.MemberInfo, exp));
        }
        private static MemberAssignment BindEnumerableExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary<ExpressionRequest, int> typePairCount)
        {
            var destinationListType = GetDestinationListTypeFor(propertyMap);

            var sourceListType = result.Type.IsArray ? result.Type.GetElementType() : result.Type.GetTypeInfo().GenericTypeArguments.First();
            var listTypePair = new ExpressionRequest(sourceListType, destinationListType, request.MembersToExpand);

            Expression exp = result.ResolutionExpression;

            if (sourceListType != destinationListType)
            {
                var transformedExpression = configuration.ExpressionBuilder.CreateMapExpression(listTypePair, typePairCount);
                if(transformedExpression == null)
                {
                    return null;
                }
                exp = Expression.Call(
                        typeof (Enumerable),
                        "Select",
                        new[] {sourceListType, destinationListType},
                        result.ResolutionExpression,
                        transformedExpression);
            }
            

            if (typeof (IList<>).MakeGenericType(destinationListType)
                .GetTypeInfo().IsAssignableFrom(propertyMap.DestinationPropertyType.GetTypeInfo())
                ||
                typeof (ICollection<>).MakeGenericType(destinationListType)
                    .GetTypeInfo().IsAssignableFrom(propertyMap.DestinationPropertyType.GetTypeInfo()))
            {
                // Call .ToList() on IEnumerable
                exp = GetToListCallExpression(propertyMap, destinationListType, exp);                
            }
            else if (propertyMap.DestinationPropertyType.IsArray)
            {
                // Call .ToArray() on IEnumerable
                exp = Expression.Call(
                        typeof (Enumerable),
                        "ToArray",
                        new[] {destinationListType},
                        exp);
            }
            
            if(configuration.AllowNullCollections) {
                exp = Expression.Condition(
                            Expression.NotEqual(
                                Expression.TypeAs(result.ResolutionExpression, typeof(object)), 
                                Expression.Constant(null)),
                            exp,
                            Expression.Constant(null, propertyMap.DestinationPropertyType));
            }

            return Expression.Bind(propertyMap.DestinationProperty.MemberInfo, exp);
        }
예제 #12
0
        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);
        }
예제 #13
0
        private static MemberAssignment BindEnumerableExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary <ExpressionRequest, int> typePairCount)
        {
            MemberAssignment bindExpression;
            Type             destinationListType = GetDestinationListTypeFor(propertyMap);

            var sourceListType = result.Type.IsArray ? result.Type.GetElementType() : result.Type.GetTypeInfo().GenericTypeArguments.First();
            var listTypePair   = new ExpressionRequest(sourceListType, destinationListType, request.MembersToExpand);

            var selectExpression = result.ResolutionExpression;

            if (sourceListType != destinationListType)
            {
                var transformedExpression = configuration.ExpressionBuilder.CreateMapExpression(listTypePair, typePairCount);
                if (transformedExpression == null)
                {
                    return(null);
                }
                selectExpression = Expression.Call(
                    typeof(Enumerable),
                    "Select",
                    new[] { sourceListType, destinationListType },
                    result.ResolutionExpression,
                    transformedExpression);
            }

            if (typeof(IList <>).MakeGenericType(destinationListType)
                .GetTypeInfo().IsAssignableFrom(propertyMap.DestinationPropertyType.GetTypeInfo())
                ||
                typeof(ICollection <>).MakeGenericType(destinationListType)
                .GetTypeInfo().IsAssignableFrom(propertyMap.DestinationPropertyType.GetTypeInfo()))
            {
                // Call .ToList() on IEnumerable
                var toListCallExpression = GetToListCallExpression(propertyMap, destinationListType, selectExpression);

                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, toListCallExpression);
            }
            else if (propertyMap.DestinationPropertyType.IsArray)
            {
                // Call .ToArray() on IEnumerable
                MethodCallExpression toArrayCallExpression = Expression.Call(
                    typeof(Enumerable),
                    "ToArray",
                    new[] { destinationListType },
                    selectExpression);
                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, toArrayCallExpression);
            }
            else
            {
                // destination type implements ienumerable, but is not an ilist. allow deferred enumeration
                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, selectExpression);
            }
            return(bindExpression);
        }
        private static MemberAssignment BindEnumerableExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary<ExpressionRequest, int> typePairCount)
        {
            MemberAssignment bindExpression;
            Type destinationListType = GetDestinationListTypeFor(propertyMap);

            var sourceListType = result.Type.IsArray ? result.Type.GetElementType() : result.Type.GetTypeInfo().GenericTypeArguments.First();
            var listTypePair = new ExpressionRequest(sourceListType, destinationListType, request.MembersToExpand);

            var selectExpression = result.ResolutionExpression;
            if (sourceListType != destinationListType)
            {
                var transformedExpression = configuration.ExpressionBuilder.CreateMapExpression(listTypePair, typePairCount);
                if(transformedExpression == null)
                {
                    return null;
                }
                selectExpression = Expression.Call(
                    typeof (Enumerable),
                    "Select",
                    new[] {sourceListType, destinationListType},
                    result.ResolutionExpression,
                    transformedExpression);
            }

            if (typeof (IList<>).MakeGenericType(destinationListType)
                .GetTypeInfo().IsAssignableFrom(propertyMap.DestinationPropertyType.GetTypeInfo())
                ||
                typeof (ICollection<>).MakeGenericType(destinationListType)
                    .GetTypeInfo().IsAssignableFrom(propertyMap.DestinationPropertyType.GetTypeInfo()))
            {
                // Call .ToList() on IEnumerable
                var toListCallExpression = GetToListCallExpression(propertyMap, destinationListType, selectExpression);

                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, toListCallExpression);
            }
            else if (propertyMap.DestinationPropertyType.IsArray)
            {
                // Call .ToArray() on IEnumerable
                MethodCallExpression toArrayCallExpression = Expression.Call(
                    typeof (Enumerable),
                    "ToArray",
                    new[] {destinationListType},
                    selectExpression);
                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, toArrayCallExpression);
            }
            else
            {
                // destination type implements ienumerable, but is not an ilist. allow deferred enumeration
                bindExpression = Expression.Bind(propertyMap.DestinationProperty.MemberInfo, selectExpression);
            }
            return bindExpression;
        }
        private static MemberAssignment BindMappedTypeExpression(IMappingEngine mappingEngine, PropertyMap propertyMap,
            ExpressionRequest request, ExpressionResolutionResult result, Internal.IDictionary<ExpressionRequest, int> typePairCount)
        {
            var transformedExpression = ((IMappingEngineRunner)mappingEngine).CreateMapExpression(request, result.ResolutionExpression, typePairCount);

            // Handles null source property so it will not create an object with possible non-nullable propeerties
            // which would result in an exception.
            if (mappingEngine.ConfigurationProvider.MapNullSourceValuesAsNull)
            {
                var expressionNull = Expression.Constant(null, propertyMap.DestinationPropertyType);
                transformedExpression =
                    Expression.Condition(Expression.NotEqual(result.ResolutionExpression, Expression.Constant(null)),
                        transformedExpression, expressionNull);
            }

            return Expression.Bind(propertyMap.DestinationProperty.MemberInfo, transformedExpression);
        }
        private static MemberAssignment BindMappedTypeExpression(IMappingEngine mappingEngine, PropertyMap propertyMap,
                                                                 ExpressionRequest request, ExpressionResolutionResult result, Internal.IDictionary <ExpressionRequest, int> typePairCount)
        {
            var transformedExpression = ((IMappingEngineRunner)mappingEngine).CreateMapExpression(request, result.ResolutionExpression, typePairCount);

            // Handles null source property so it will not create an object with possible non-nullable propeerties
            // which would result in an exception.
            if (mappingEngine.ConfigurationProvider.AllowNullDestinationValues)
            {
                var expressionNull = Expression.Constant(null, propertyMap.DestinationPropertyType);
                transformedExpression =
                    Expression.Condition(Expression.NotEqual(result.ResolutionExpression, Expression.Constant(null)),
                                         transformedExpression, expressionNull);
            }

            return(Expression.Bind(propertyMap.DestinationProperty.MemberInfo, transformedExpression));
        }
예제 #17
0
        private List <MemberBinding> CreateMemberBindings(ExpressionRequest request,
                                                          TypeMap typeMap,
                                                          Expression instanceParameter, Internal.IDictionary <ExpressionRequest, int> typePairCount)
        {
            var bindings = new List <MemberBinding>();

            var visitCount = typePairCount.AddOrUpdate(request, 0, (tp, i) => i + 1);

            if (visitCount >= typeMap.MaxDepth)
            {
                return(bindings);
            }

            foreach (var propertyMap in typeMap.GetPropertyMaps().Where(pm => pm.CanResolveValue()))
            {
                var result = ResolveExpression(propertyMap, request.SourceType, instanceParameter);

                if (propertyMap.ExplicitExpansion &&
                    !request.MembersToExpand.Contains(propertyMap.DestinationProperty.MemberInfo))
                {
                    continue;
                }

                var propertyTypeMap = ConfigurationProvider.ResolveTypeMap(result.Type,
                                                                           propertyMap.DestinationPropertyType);
                var propertyRequest = new ExpressionRequest(result.Type, propertyMap.DestinationPropertyType,
                                                            request.MembersToExpand);

                var binder = 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.DestinationProperty.MemberInfo.DeclaringType?.Name}.{propertyMap.DestinationProperty.Name} ({propertyMap.DestinationPropertyType})";

                    throw new AutoMapperMappingException(message);
                }

                var bindExpression = binder.Build(this, propertyMap, propertyTypeMap, propertyRequest, result,
                                                  typePairCount);

                bindings.Add(bindExpression);
            }
            return(bindings);
        }
예제 #18
0
        private static MemberAssignment BindEnumerableExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary <ExpressionRequest, int> typePairCount, LetPropertyMaps letPropertyMaps)
        {
            var expression = result.ResolutionExpression;

            if (propertyMap.DestinationPropertyType != expression.Type)
            {
                var destinationListType    = ElementTypeHelper.GetElementType(propertyMap.DestinationPropertyType);
                var sourceListType         = ElementTypeHelper.GetElementType(propertyMap.SourceType);
                var listTypePair           = new ExpressionRequest(sourceListType, destinationListType, request.MembersToExpand, request);
                var transformedExpressions = configuration.ExpressionBuilder.CreateMapExpression(listTypePair, typePairCount, letPropertyMaps.New());
                if (transformedExpressions == null)
                {
                    return(null);
                }
                expression = transformedExpressions.Aggregate(expression, (source, lambda) => Select(source, lambda));
            }

            return(Expression.Bind(propertyMap.DestinationProperty, expression));
        }
        private static MemberAssignment BindMappedTypeExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary<ExpressionRequest, int> typePairCount)
        {
            var transformedExpression = configuration.ExpressionBuilder.CreateMapExpression(request, result.ResolutionExpression, typePairCount);
            if(transformedExpression == null)
            {
                return null;
            }
            // Handles null source property so it will not create an object with possible non-nullable propeerties 
            // which would result in an exception.
            if (propertyMap.TypeMap.Profile.AllowNullDestinationValues && !propertyMap.AllowNull)
            {
                var expressionNull = Expression.Constant(null, propertyMap.DestinationPropertyType);
                transformedExpression =
                    Expression.Condition(Expression.NotEqual(result.ResolutionExpression, Expression.Constant(null)),
                        transformedExpression, expressionNull);
            }

            return Expression.Bind(propertyMap.DestinationProperty, transformedExpression);
        }
        private static MemberAssignment BindEnumerableExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary <ExpressionRequest, int> typePairCount)
        {
            var destinationListType = TypeHelper.GetElementType(propertyMap.DestinationPropertyType);
            var sourceListType      = TypeHelper.GetElementType(propertyMap.SourceType);
            var expression          = result.ResolutionExpression;

            if (sourceListType != destinationListType)
            {
                var listTypePair          = new ExpressionRequest(sourceListType, destinationListType, request.MembersToExpand);
                var transformedExpression = configuration.ExpressionBuilder.CreateMapExpression(listTypePair, typePairCount);
                if (transformedExpression == null)
                {
                    return(null);
                }
                expression = Expression.Call(typeof(Enumerable), "Select", new[] { sourceListType, destinationListType }, result.ResolutionExpression, transformedExpression);
            }

            expression = Expression.Call(typeof(Enumerable), propertyMap.DestinationPropertyType.IsArray ? "ToArray" : "ToList", new[] { destinationListType }, expression);

            return(Expression.Bind(propertyMap.DestinationProperty, expression));
        }
예제 #21
0
 public MemberAssignment Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary<ExpressionRequest, int> typePairCount)
 {
     return BindStringExpression(propertyMap, result);
 }
 public MemberAssignment Build(IMappingEngine mappingEngine, PropertyMap propertyMap, TypeMap propertyTypeMap,
     ExpressionRequest request, ExpressionResolutionResult result, Internal.IDictionary<ExpressionRequest, int> typePairCount)
 {
     return BindMappedTypeExpression(mappingEngine, propertyMap, request, result, typePairCount);
 }
 public MemberAssignment Build(IMappingEngine mappingEngine, PropertyMap propertyMap, TypeMap propertyTypeMap,
                               ExpressionRequest request, ExpressionResolutionResult result,
                               IDictionary <ExpressionRequest, int> typePairCount)
 {
     return(BindAssignableExpression(propertyMap, result));
 }
 public MemberAssignment Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary <ExpressionRequest, int> typePairCount, LetPropertyMaps letPropertyMaps)
 => BindMappedTypeExpression(configuration, propertyMap, request, result, typePairCount, letPropertyMaps);
예제 #25
0
            public override QueryExpressions GetSubQueryExpression(ExpressionBuilder builder, Expression projection, TypeMap typeMap, ExpressionRequest request, Expression instanceParameter, TypePairCount typePairCount)
            {
                var letMapInfos = _savedPaths.Select(path =>
                                                     new {
                    path.LetExpression,
                    MapFromSource = path.GetSourceExpression(instanceParameter),
                    Property      = path.GetPropertyDescription(),
                    path.Marker
                }).ToArray();

                var properties = letMapInfos.Select(m => m.Property).Concat(GetMemberAccessesVisitor.Retrieve(projection, instanceParameter));

                var     letType = ProxyGenerator.GetSimilarType(typeof(object), properties);
                TypeMap letTypeMap;

                lock (ConfigurationProvider)
                {
                    letTypeMap = TypeMapFactory.CreateTypeMap(request.SourceType, letType, typeMap.Profile);
                }
                var secondParameter = Parameter(letType, "dtoLet");

                ReplaceSubQueries();

                var firstExpression = builder.CreateMapExpressionCore(request, instanceParameter, typePairCount, letTypeMap, base.New());

                return(new QueryExpressions(firstExpression, projection, secondParameter));

                void ReplaceSubQueries()
                {
                    foreach (var letMapInfo in letMapInfos)
                    {
                        var letProperty    = letType.GetProperty(letMapInfo.Property.Name);
                        var letPropertyMap = letTypeMap.FindOrCreatePropertyMapFor(letProperty);
                        letPropertyMap.CustomMapExpression = Lambda(letMapInfo.LetExpression.ReplaceParameters(letMapInfo.MapFromSource), secondParameter);
                        projection = projection.Replace(letMapInfo.Marker, MakeMemberAccess(secondParameter, letProperty));
                    }
                    projection = new ReplaceMemberAccessesVisitor(instanceParameter, secondParameter).Visit(projection);
                }
            }
예제 #26
0
 public MemberAssignment Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary <ExpressionRequest, int> typePairCount, LetPropertyMaps letPropertyMaps) =>
 Bind(propertyMap.DestinationProperty, Convert(result.ResolutionExpression, propertyMap.DestinationPropertyType));
 public MemberAssignment Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary <ExpressionRequest, int> typePairCount)
 => BindNullableExpression(propertyMap, result);
 public MemberAssignment Build(IMappingEngine mappingEngine, PropertyMap propertyMap, TypeMap propertyTypeMap,
     ExpressionRequest request, ExpressionResolutionResult result,
     IDictionary<ExpressionRequest, int> typePairCount)
 {
     return BindNullableExpression(propertyMap, result);
 }
 public MemberAssignment Build(IMappingEngine mappingEngine, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary <ExpressionRequest, int> typePairCount)
 {
     return(BindCustomProjectionExpression(propertyMap, propertyTypeMap, result));
 }
예제 #30
0
        public MemberAssignment Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary <ExpressionRequest, int> typePairCount, LetPropertyMaps letPropertyMaps)
        {
            var defaultDestination = Activator.CreateInstance(propertyMap.DestinationType);

            return(Expression.Bind(propertyMap.DestinationMember, Expression.Coalesce(result.ResolutionExpression, Expression.Constant(defaultDestination))));
        }
예제 #31
0
 public MemberAssignment Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary <ExpressionRequest, int> typePairCount)
 {
     return(BindMappedTypeExpression(configuration, propertyMap, request, result, typePairCount));
 }
예제 #32
0
        private static MemberAssignment BindMappedTypeExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, ConcurrentDictionary <ExpressionRequest, int> typePairCount)
        {
            var transformedExpression = configuration.ExpressionBuilder.CreateMapExpression(request, result.ResolutionExpression, typePairCount);

            if (transformedExpression == null)
            {
                return(null);
            }
            // Handles null source property so it will not create an object with possible non-nullable propeerties
            // which would result in an exception.
            if (configuration.Configuration.AllowNullDestinationValues && !propertyMap.AllowNull)
            {
                var expressionNull = Expression.Constant(null, propertyMap.DestType);
                transformedExpression =
                    Expression.Condition(Expression.NotEqual(result.ResolutionExpression, Expression.Constant(null)),
                                         transformedExpression, expressionNull);
            }

            return(Expression.Bind(propertyMap.DestMember, transformedExpression));
        }
예제 #33
0
 public MemberAssignment Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary <ExpressionRequest, int> typePairCount)
 {
     return(BindCustomProjectionExpression(propertyMap, propertyTypeMap, result));
 }
        private static MemberAssignment BindMappedTypeExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary <ExpressionRequest, int> typePairCount, LetPropertyMaps letPropertyMaps)
        {
            var transformedExpression = configuration.ExpressionBuilder.CreateMapExpression(request, result.ResolutionExpression, typePairCount, letPropertyMaps);

            if (transformedExpression == null)
            {
                return(null);
            }
            // Handles null source property so it will not create an object with possible non-nullable properties
            // which would result in an exception.
            if (propertyMap.TypeMap.Profile.AllowNullDestinationValues && !propertyMap.AllowNull && !(result.ResolutionExpression is ParameterExpression))
            {
                transformedExpression = result.ResolutionExpression.IfNullElse(Constant(null, transformedExpression.Type), transformedExpression);
            }

            return(Bind(propertyMap.DestinationProperty, transformedExpression));
        }
 public MemberAssignment Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary<ExpressionRequest, int> typePairCount)
 {
     return BindMappedTypeExpression(configuration, propertyMap, request, result, typePairCount);
 }