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()); }
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()); }
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); }
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); }