Ejemplo n.º 1
0
        protected override void CompileInternal()
        {
            if (ResultMapFunction != null)
            {
                return;
            }

            var destVariable = GetDestionationVariable();

            ProcessCustomMembers();
            ProcessCustomFunctionMembers();
            ProcessFlattenedMembers();
            ProcessAutoProperties();

            CreateQueryableProjection();

            var expressions = new List <Expression> {
                destVariable
            };

            if (BeforeMapHandler != null)
            {
                Expression <Action <T, TN> > beforeExpression = (src, dest) => BeforeMapHandler(src, dest);
                var beforeInvokeExpr = Expression.Invoke(beforeExpression, SourceParameter, destVariable.Left);
                expressions.Add(beforeInvokeExpr);
            }

            expressions.AddRange(PropertyCache.Values);

            var customProps = CustomPropertyCache.Where(k => !IgnoreMemberList.Contains(k.Key)).Select(k => k.Value);

            expressions.AddRange(customProps);

            if (AfterMapHandler != null)
            {
                Expression <Action <T, TN> > afterExpression = (src, dest) => AfterMapHandler(src, dest);
                var afterInvokeExpr = Expression.Invoke(afterExpression, SourceParameter, destVariable.Left);
                expressions.Add(afterInvokeExpr);
            }

            ResultExpressionList.AddRange(expressions);
            expressions.Add(destVariable.Left);

            var variables = new List <ParameterExpression>();

            var finalExpression = Expression.Block(variables, expressions);

            var destExpression = destVariable.Left as ParameterExpression;

            var substituteParameterVisitor =
                new PreciseSubstituteParameterVisitor(
                    new KeyValuePair <ParameterExpression, ParameterExpression>(SourceParameter, SourceParameter),
                    new KeyValuePair <ParameterExpression, ParameterExpression>(destExpression, destExpression));

            var resultExpression = substituteParameterVisitor.Visit(finalExpression) as BlockExpression;

            var expression = Expression.Lambda <Func <T, TN, TN> >(resultExpression, SourceParameter, DestFakeParameter);

            ResultMapFunction = expression.Compile();
        }
Ejemplo n.º 2
0
        protected override void CompileInternal()
        {
            if (this.ResultMapFunction != null)
            {
                return;
            }

            this.ProcessCustomMembers();
            this.ProcessCustomFunctionMembers();
            this.ProcessFlattenedMembers();
            this.ProcessAutoProperties();

            var expressions = new List <Expression>();

            if (this.BeforeMapHandler != null)
            {
                Expression <Action <T, TN> > beforeExpression = (src, dest) => this.BeforeMapHandler(src, dest);
                var beforeInvokeExpr = Expression.Invoke(beforeExpression, this.SourceParameter, this.DestFakeParameter);
                expressions.Add(beforeInvokeExpr);
            }

            expressions.AddRange(this.PropertyCache.Values);

            var customProps = this.CustomPropertyCache.Where(k => !this.IgnoreMemberList.Contains(k.Key)).Select(k => k.Value);

            expressions.AddRange(customProps);

            if (this.AfterMapHandler != null)
            {
                Expression <Action <T, TN> > afterExpression = (src, dest) => this.AfterMapHandler(src, dest);
                var afterInvokeExpr = Expression.Invoke(afterExpression, this.SourceParameter, this.DestFakeParameter);
                expressions.Add(afterInvokeExpr);
            }

            this.ResultExpressionList.AddRange(expressions);
            this.ResultExpressionList.Insert(0, this.GetDestionationVariable());

            expressions.Add(this.DestFakeParameter);

            var finalExpression = Expression.Block(expressions);

            var substituteParameterVisitor =
                new PreciseSubstituteParameterVisitor(
                    new KeyValuePair <ParameterExpression, ParameterExpression>(this.SourceParameter, this.SourceParameter),
                    new KeyValuePair <ParameterExpression, ParameterExpression>(this.DestFakeParameter, this.DestFakeParameter));

            //var substituteParameterVisitor = new SubstituteParameterVisitor(SourceParameter, DestFakeParameter);

            var resultExpression = substituteParameterVisitor.Visit(finalExpression);

            var expression = Expression.Lambda <Func <T, TN, TN> >(resultExpression, this.SourceParameter, this.DestFakeParameter);

            this.ResultMapFunction = expression.Compile();
        }
Ejemplo n.º 3
0
        public Expression GetMemberMappingExpression(Expression left, Expression right)
        {
            var nullCheckNestedMemberVisitor = new NullCheckNestedMemberVisitor(false);

            nullCheckNestedMemberVisitor.Visit(right);

            var destNullableType   = Nullable.GetUnderlyingType(left.Type);
            var sourceNullableType = Nullable.GetUnderlyingType(right.Type);

            var destType   = destNullableType ?? left.Type;
            var sourceType = sourceNullableType ?? right.Type;

            if (ComplexMapCondition(sourceType, destType))
            {
                var customMapExpression = GetCustomMapExpression(right.Type, left.Type);
                if (customMapExpression != null)
                {
                    var srcExp = Expression.Variable(right.Type,
                                                     string.Format("{0}Src", Guid.NewGuid().ToString("N")));
                    var assignSrcExp = Expression.Assign(srcExp, right);

                    var destExp = Expression.Variable(left.Type,
                                                      string.Format("{0}Dst", Guid.NewGuid().ToString("N")));
                    var assignDestExp = Expression.Assign(destExp, left);

                    // try precise substitute visitor
                    var substituteParameterVisitor =
                        new PreciseSubstituteParameterVisitor(
                            new KeyValuePair <ParameterExpression, ParameterExpression>(
                                Expression.Variable(right.Type, "srcTyped"), srcExp),
                            new KeyValuePair <ParameterExpression, ParameterExpression>(
                                Expression.Variable(left.Type, "dstTyped"), destExp));

                    var blockExpression = substituteParameterVisitor.Visit(customMapExpression) as BlockExpression;

                    var assignResultExp = Expression.Assign(left, destExp);
                    var resultBlockExp  = Expression.Block(new[] { srcExp, destExp }, assignSrcExp, assignDestExp, blockExpression, assignResultExp);

                    var checkNullExp =
                        Expression.IfThenElse(Expression.Equal(right, Expression.Default(right.Type)),
                                              Expression.Assign(left, Expression.Default(left.Type)), resultBlockExp);

                    var releaseExp = Expression.Block(new ParameterExpression[] { }, checkNullExp);

                    return(releaseExp);
                }

                var returnTypeDifferenceVisitor = new ReturnTypeDifferenceVisitor(right);
                returnTypeDifferenceVisitor.Visit(right);

                // If right is custom member expression / func and return type matches left type
                // just assign
                if (left.Type == right.Type && returnTypeDifferenceVisitor.DifferentReturnTypes)
                {
                    return(Expression.Assign(left, right));
                }

                if (typeof(IConvertible).IsAssignableFrom(destType) &&
                    typeof(IConvertible).IsAssignableFrom(sourceType))
                {
                    var assignExp = CreateConvertibleAssignExpression(left,
                                                                      right,
                                                                      left.Type,
                                                                      sourceType,
                                                                      destNullableType);

                    return(assignExp);
                }
                var mapComplexResult = GetDifferentTypeMemberMappingExpression(right, left);

                return(nullCheckNestedMemberVisitor.CheckNullExpression != null
                    ? Expression.Condition(nullCheckNestedMemberVisitor.CheckNullExpression,
                                           Expression.Assign(left, Expression.Default(left.Type)),
                                           mapComplexResult)
                    : mapComplexResult);
            }
            var binaryExpression = CreateAssignExpression(left,
                                                          right,
                                                          left.Type,
                                                          destNullableType,
                                                          sourceNullableType);

            var conditionalExpression = nullCheckNestedMemberVisitor.CheckNullExpression != null?Expression.Condition(nullCheckNestedMemberVisitor.CheckNullExpression, Expression.Assign(left, Expression.Default(left.Type)), binaryExpression) : (Expression)binaryExpression;

            return(conditionalExpression);
        }
Ejemplo n.º 4
0
        protected override void CompileInternal()
        {
            if (this.ResultMapFunction != null)
            {
                return;
            }

            BinaryExpression destVariable = this.GetDestionationVariable();

            this.ProcessCustomMembers();
            this.ProcessCustomFunctionMembers();
            this.ProcessFlattenedMembers();
            this.ProcessAutoProperties();

            this.CreateQueryableProjection();

            List <Expression> expressions = new List <Expression> {
                destVariable
            };

            if (this.BeforeMapHandler != null)
            {
                Expression <Action <T, TN> > beforeExpression = (src, dest) => this.BeforeMapHandler(src, dest);
                InvocationExpression         beforeInvokeExpr = Expression.Invoke(beforeExpression, this.SourceParameter, destVariable.Left);
                expressions.Add(beforeInvokeExpr);
            }

            expressions.AddRange(this.PropertyCache.Values);

            IEnumerable <Expression> customProps = this.CustomPropertyCache.Where(k => !this.IgnoreMemberList.Contains(k.Key))
                                                   .Select(k => k.Value);

            expressions.AddRange(customProps);

            if (this.AfterMapHandler != null)
            {
                Expression <Action <T, TN> > afterExpression = (src, dest) => this.AfterMapHandler(src, dest);
                InvocationExpression         afterInvokeExpr = Expression.Invoke(afterExpression, this.SourceParameter, destVariable.Left);
                expressions.Add(afterInvokeExpr);
            }

            this.ResultExpressionList.AddRange(expressions);
            expressions.Add(destVariable.Left);

            List <ParameterExpression> variables = new List <ParameterExpression>();

            BlockExpression finalExpression = Expression.Block(variables, expressions);

            ParameterExpression destExpression = destVariable.Left as ParameterExpression;

            PreciseSubstituteParameterVisitor substituteParameterVisitor = new PreciseSubstituteParameterVisitor(
                new KeyValuePair <ParameterExpression, ParameterExpression>(this.SourceParameter, this.SourceParameter),
                new KeyValuePair <ParameterExpression, ParameterExpression>(destExpression, destExpression));

            BlockExpression resultExpression = substituteParameterVisitor.Visit(finalExpression) as BlockExpression;

            Expression <Func <T, TN, TN> > expression = Expression.Lambda <Func <T, TN, TN> >(
                resultExpression,
                this.SourceParameter,
                this.DestFakeParameter);

            this.ResultMapFunction = expression.Compile();
        }