protected override Expression <Func <TFrom, TTo, TTo> > CompileToExpression()
        {
            var from = Expression.Parameter(typeof(TFrom), "from");
            var to   = Expression.Parameter(typeof(TTo), "to");

            var temporaryVariables = new TemporaryVariables(this.aMemberPairs, from, to);

            return(Expression.Lambda <Func <TFrom, TTo, TTo> >(
                       Expression.Block(
                           temporaryVariables.Variables,

                           this.MakeBlock(
                               temporaryVariables.InitialAssignments
                               ),
                           this.MakeBlock(
                               this.aMemberPairs.Select(
                                   x => x.CreateSynchronizationAssignmentExpression(
                                       x.From.Parent == null ? from : temporaryVariables[x.From.Parent],
                                       x.To.Parent == null ? to : temporaryVariables[x.To.Parent],
                                       this.aMappingDefinition.GetChildPostprocessing(typeof(TTo), x.To.Type),
                                       to
                                       )
                                   )
                               ),
                           this.MakeBlock(
                               temporaryVariables.FinalAssignments
                               ),
                           to
                           ),
                       from, to
                       ));
        }
        protected override Expression <Func <TFrom, TTo, bool> > CompileToExpression()
        {
            var from = Expression.Parameter(typeof(TFrom), "from");
            var to   = Expression.Parameter(typeof(TTo), "to");

            var end = Expression.Label(typeof(bool));

            var pairedMembers = this.aMemberPairs.ToList();

            var temporaryVariables = new TemporaryVariables(pairedMembers, from, to);

            return(Expression.Lambda <Func <TFrom, TTo, bool> >(
                       Expression.Block(
                           temporaryVariables.Variables,
                           this.MakeBlock(temporaryVariables.InitialAssignments),
                           this.MakeBlock(
                               pairedMembers.Select(
                                   x => x.CreateComparisionExpression(
                                       x.From.Parent == null ? from : temporaryVariables[x.From.Parent],
                                       x.To.Parent == null ? to : temporaryVariables[x.To.Parent],
                                       end
                                       )
                                   )
                               ),
                           Expression.Label(end, Expression.Constant(true))
                           ),
                       from, to
                       ));
        }
Exemplo n.º 3
0
        public TemporaryVariables(IEnumerable <PairedMembers> memberPairs, ParameterExpression from, ParameterExpression to)
        {
            this.aTemporaryVariables = new Dictionary <IMember, ParameterExpression>();
            this.InitialAssignments  = new List <Expression>();
            this.FinalAssignments    = new List <Expression>();

            foreach (PairedMembers memberPair in memberPairs)
            {
                foreach (IMember parent in this.GetAllMemberParents(memberPair.From, this.aTemporaryVariables))
                {
                    ParameterExpression parentVariable = parent.Parent == null ? from : this.aTemporaryVariables[parent.Parent];
                    this.InitialAssignments.Add(
                        Expression.Assign(
                            this.aTemporaryVariables[parent],
                            parent.CreateGetterExpression(parentVariable)
                            )
                        );
                }
            }

            foreach (PairedMembers memberPair in memberPairs)
            {
                foreach (IMember parent in this.GetAllMemberParents(memberPair.To, this.aTemporaryVariables))
                {
                    ParameterExpression parentVariable = parent.Parent == null ? to : this.aTemporaryVariables[parent.Parent];

                    this.InitialAssignments.Add(
                        Expression.Assign(
                            this.aTemporaryVariables[parent],
                            TemporaryVariables.BetterCoalesce(
                                parent.CreateGetterExpression(parentVariable),
                                TemporaryVariables.NewExpression(parent.Type)
                                )
                            )
                        );

                    Expression setterExpression = parent.CreateSetterExpression(
                        parentVariable,
                        this.aTemporaryVariables[parent]
                        );
                    if (setterExpression != null)
                    {
                        this.FinalAssignments.Add(setterExpression);
                    }
                }
            }
        }
        protected override Expression <Func <TFrom, TTo> > CompileToExpression()
        {
            var from = Expression.Parameter(typeof(TFrom), "from");
            var to   = Expression.Parameter(typeof(TTo), "to");

            var pairedMembers = this.aMemberPairs.ToList();

            var temporaryVariables = new TemporaryVariables(pairedMembers, from, to);

            Expression body = Expression.Block(
                new ParameterExpression[] { to }.Concat(temporaryVariables.Variables),

                Expression.Assign(
                    to,
                    this.NewExpression(from, typeof(TTo))
                    ),
                this.MakeBlock(
                    temporaryVariables.InitialAssignments
                    ),
                this.MakeBlock(
                    pairedMembers.Select(
                        x => x.CreateMappingAssignmentExpression(
                            x.From.Parent == null ? from : temporaryVariables[x.From.Parent],
                            x.To.Parent == null ? to : temporaryVariables[x.To.Parent],
                            this.aMappingDefinition.GetChildPostprocessing(typeof(TTo), x.To.Type),
                            to
                            )
                        )
                    ),
                this.MakeBlock(
                    temporaryVariables.FinalAssignments
                    ),
                to
                );

            return(Expression.Lambda <Func <TFrom, TTo> >(
                       body,
                       from
                       ));
        }