Example #1
0
        public virtual Action <TSource, TTarget, CircularRefChecker> GenerateDefaultCopyToDelegate()
        {
            Type sType = typeof(TSource);
            Type tType = typeof(TTarget);

            ParameterExpression sourcePar    = Expression.Parameter(sType, "source");
            ParameterExpression targetPar    = Expression.Parameter(tType, "target");
            ParameterExpression targetVar    = Expression.Variable(tType);
            ParameterExpression crCheckerPar = Expression.Parameter(typeof(CircularRefChecker), "checker");


            var g   = new PropertyAssignGenerator(sourcePar, targetVar, crCheckerPar, _provider);
            var exp = g.GenerateExpression();


            List <Expression> expList = new List <Expression>()
            {
            };

            if (exp != null)
            {
                if (PropertyAssignGenerator.IsDictionaryType(tType))
                {
                    var        argTypes = tType.GetGenericArguments();
                    MethodInfo mi       = this.GetType().GetMethod("CopyToDictionay");
                    mi = mi.MakeGenericMethod(argTypes[0], argTypes[1]);

                    expList.Add(exp);
                    expList.Add(Expression.Call(Expression.Constant(this), mi, targetVar, targetPar));
                }
                else if (PropertyAssignGenerator.IsListType(tType))
                {
                    var        argTypes = tType.GetGenericArguments();
                    MethodInfo mi       = this.GetType().GetMethod("CopyToList");
                    mi = mi.MakeGenericMethod(argTypes[0]);

                    expList.Add(exp);
                    expList.Add(Expression.Call(Expression.Constant(this), mi, targetVar, targetPar));
                }
                else
                {
                    // 单值不存在CopyTo
                    return((s, t, checker) => { });
                }
            }
            else
            {
                // 类转换
                expList.AddRange(GeneratePropertyAssignExpression(sourcePar, targetPar, crCheckerPar, true));
            }


            return(Expression.Lambda <Action <TSource, TTarget, CircularRefChecker> >(
                       Expression.Block(
                           new ParameterExpression[] { targetVar },
                           Expression.IfThen(
                               Expression.NotEqual(Expression.Constant(targetPar), Expression.Constant(null)),
                               Expression.Block(expList))
                           ), sourcePar, targetPar, crCheckerPar).Compile());
        }
Example #2
0
        public virtual Func <TSource, CircularRefChecker, TTarget> GenerateDefaultConvertDelegate()
        {
            Type sType = typeof(TSource);
            Type tType = typeof(TTarget);

            ParameterExpression sourcePar     = Expression.Parameter(sType, "source");
            ParameterExpression targetVar     = Expression.Variable(tType, "target");
            ParameterExpression checkerPar    = Expression.Parameter(typeof(CircularRefChecker), "checker");
            ParameterExpression cacheValueVar = Expression.Variable(tType, "cacheVal");



            var g   = new PropertyAssignGenerator(sourcePar, targetVar, checkerPar, _provider);
            var exp = g.GenerateExpression();


            List <Expression> expList = new List <Expression>()
            {
            };

            if (exp != null)
            {
                // 非Class类型
                expList.Add(exp);
            }
            else
            {
                Expression cacheValueAssign = Expression.Assign(
                    cacheValueVar,
                    Expression.Convert(Expression.Call(checkerPar, CircularRefChecker.GetValueMethod, Expression.Convert(sourcePar, typeof(object)), Expression.Constant(tType)), tType));
                expList.Add(cacheValueAssign);

                List <Expression> subExpList    = new List <Expression>();
                Expression        newExpression = Expression.Assign(targetVar, Expression.New(tType));
                subExpList.Add(newExpression);
                subExpList.Add(Expression.Call(checkerPar, CircularRefChecker.SetInstanceMethod, sourcePar, Expression.Constant(tType), targetVar));
                subExpList.AddRange(GeneratePropertyAssignExpression(sourcePar, targetVar, checkerPar, false));

                expList.Add(
                    Expression.IfThenElse(
                        Expression.Equal(cacheValueVar, Expression.Constant(null)),
                        Expression.Block(subExpList),
                        Expression.Assign(targetVar, cacheValueVar)
                        ));
            }
            expList.Add(targetVar);

            Expression block = Expression.Block(
                new ParameterExpression[] { targetVar, cacheValueVar },
                expList
                );

            return(Expression.Lambda <Func <TSource, CircularRefChecker, TTarget> >(block, sourcePar, checkerPar).Compile());
        }
Example #3
0
        private Func <TSource, TTarget> GenerateConverter <TSource, TTarget>(IMapperProvider provider)
        {
            ParameterExpression     s          = Expression.Parameter(typeof(TSource));
            ParameterExpression     t          = Expression.Variable(typeof(TTarget));
            ParameterExpression     checkerVar = Expression.Variable(typeof(CircularRefChecker));
            PropertyAssignGenerator g          = new PropertyAssignGenerator(s, t, checkerVar, provider);
            var expression = g.GenerateExpression();

            Expression <Func <TSource, TTarget> > lam = Expression.Lambda <Func <TSource, TTarget> >(
                Expression.Block(new ParameterExpression[] { t, checkerVar },
                                 Expression.Assign(checkerVar, Expression.New(typeof(CircularRefChecker))),
                                 expression, t), s);
            Func <TSource, TTarget> func = lam.Compile();

            return(func);
        }
Example #4
0
        public virtual Expression ConvertProperty(ParameterExpression source, ParameterExpression checkerPar, PropertyInfo spi, Expression target, PropertyInfo tpi, bool isCopy, MemberInitExpression excludeProperties)
        {
            ParameterExpression se = ParameterExpression.Variable(spi.PropertyType);
            ParameterExpression te = ParameterExpression.Variable(tpi.PropertyType);

            List <Expression> expList = new List <Expression>();


            PropertyAssignGenerator g = new PropertyAssignGenerator(se, te, checkerPar, _provider);
            Expression e = g.GenerateExpression(true);

            if (e != null)
            {
                expList.Add(Expression.Assign(se, Expression.MakeMemberAccess(source, spi)));
                if (isCopy)
                {
                    //拷贝
                    Type tType = tpi.PropertyType;
                    if ((tType.IsClass && tType != typeof(string)) ||
                        PropertyAssignGenerator.IsDictionaryType(tType) ||
                        PropertyAssignGenerator.IsListType(tType))
                    {
                        List <Expression> exp = new List <Expression>();
                        if (tType.IsClass)
                        {
                            exp.Add(Expression.Assign(te, Expression.MakeMemberAccess(target, tpi)));
                            if (excludeProperties != null)
                            {
                                exp.Add(GenerateExcludeAction(spi.PropertyType, tType, se, te, excludeProperties));
                            }
                            else
                            {
                                exp.Add(g.GenerateCopyToExpression());
                            }
                        }
                        else if (PropertyAssignGenerator.IsDictionaryType(tType))
                        {
                            var        argTypes = tType.GetGenericArguments();
                            MethodInfo mi       = this.GetType().GetMethod("CopyToDictionay");
                            mi = mi.MakeGenericMethod(argTypes[0], argTypes[1]);
                            exp.Add(e);
                            exp.Add(Expression.Call(Expression.Constant(this), mi, te, Expression.MakeMemberAccess(target, tpi)));
                        }
                        else if (PropertyAssignGenerator.IsListType(tType))
                        {
                            var        argTypes = tType.GetGenericArguments();
                            MethodInfo mi       = this.GetType().GetMethod("CopyToList");
                            mi = mi.MakeGenericMethod(argTypes[0]);
                            exp.Add(e);
                            exp.Add(Expression.Call(Expression.Constant(this), mi, te, Expression.MakeMemberAccess(target, tpi)));
                        }

                        // 如果te等于null,new
                        expList.Add(Expression.IfThenElse(
                                        Expression.Equal(Expression.MakeMemberAccess(target, tpi), Expression.Constant(null)),
                                        Expression.Block(
                                            e,
                                            Expression.Assign(
                                                Expression.MakeMemberAccess(target, tpi),
                                                te)
                                            ),
                                        Expression.IfThenElse(
                                            Expression.Equal(se, Expression.Constant(null)),
                                            Expression.Assign(Expression.MakeMemberAccess(target, tpi), Expression.Constant(null, tpi.PropertyType)),
                                            Expression.Block(exp)
                                            )

                                        ));

                        return(Expression.Block(
                                   new ParameterExpression[] { se, te },
                                   expList));
                    }
                }

                expList.Add(e);
                expList.Add(Expression.Assign(
                                Expression.MakeMemberAccess(target, tpi),
                                te));

                return(Expression.Block(
                           new ParameterExpression[] { se, te },
                           expList));
            }

            return(null);
        }