Ejemplo n.º 1
0
 /// <summary>
 /// Returns generator for complex type mappings.
 /// </summary>
 public static Func<Expression, Type, Expression, Expression> ComplexToComplex(Func<Expression, Type, Expression, Expression> parent, IMemberExtractor memberExtractor)
 {
     return (fromExpr, to, customMapping) =>
                 {
                         if (IsComplexType(fromExpr.Type) && IsComplexType(to))
                         {
                                 return ValidateCustomMapping(customMapping)
                                              ?? ComplexToComplexExpressionGenerator(parent, memberExtractor, fromExpr, to, customMapping);
                         }
                         else
                         {
                                 return null;
                         }
                 };
 }
Ejemplo n.º 2
0
        private static Expression ComplexToComplexExpressionGenerator(Func<Expression, Type, Expression, Expression> parent, IMemberExtractor memberExtractor, Expression fromExpr, Type to, Expression customMapping)
        {
            NewExpression configNewExpr = null;
                        IEnumerable<MemberAssignment> configBindings = Enumerable.Empty<MemberAssignment>();
                        var customInitExpression = customMapping as MemberInitExpression;
                        if (customInitExpression != null)
                        {
                                configNewExpr = customInitExpression.NewExpression;
                                configBindings = customInitExpression.Bindings.OfType<MemberAssignment>();
                        }

                        var membersTo = memberExtractor
                                                                .GetToMembers(to)
                                                                .ToList();

                        var membersFrom = memberExtractor
                                                                .GetFromMembers(fromExpr.Type, membersTo)
                                                                .ToList();

                        var conventionalBindings = (from mfrom in membersFrom
                                                                                join mto in membersTo on mfrom.Name equals mto.Name
                                                                                let memberExpr = parent(mfrom.GetMemberAccessExpression(fromExpr), mto.Type, null)
                                                                                where memberExpr != null
                                                                                select Expression.Bind(mto.Member, memberExpr)
                                                                             ).ToList();

                        //HACK : In case of no member "from" for custom mapping
                        //used binding expression as fromExpr parameter for recursive call
                        //because in this case fromExpr used only for type matching
                        var customBindings = (from b in configBindings
                                                                    join mto in membersTo on b.Member equals mto.Member
                                                                    let mfrom = membersFrom.FirstOrDefault(m => mto.Name == m.Name)
                                                                    let expr = (mfrom != null)
                                                                                         ? mfrom.GetMemberAccessExpression(fromExpr)
                                                                                         : b.Expression /*hack*/
                                                                    let memberExpr = parent(expr, mto.Type, b.Expression)
                                                                    select Expression.Bind(mto.Member, memberExpr)
                                                                 ).ToList();

                        var customBindingMembers = new HashSet<MemberInfo>(customBindings.Select(b => b.Member));
                        var allBindings = customBindings
                                                                .Concat(conventionalBindings
                                                                                        .Where(b => !customBindingMembers.Contains(b.Member)));

                        return Expression.MemberInit(configNewExpr ?? Expression.New(to), allBindings.Cast<MemberBinding>());
        }