Beispiel #1
0
        private Expression CreateItemEqualityExpression(MemberExpression fromItem, MemberExpression toItem)
        {
            Expression itemsAreMapEqual;

            if (this.aItemMapping.ResolvedMapping is IMappingWithSpecialComparision)
            {
                itemsAreMapEqual = Expression.Call(
                    Expression.Constant(this.aItemMapping.ResolvedMapping),
                    MappingMethods.MapEqual(EnumerableReflection <TFrom> .ItemType, EnumerableReflection <TTo> .ItemType),
                    fromItem,
                    toItem
                    );
            }
            else
            {
                Expression fromMapped = fromItem;

                if (!(this.aItemMapping.ResolvedMapping is IDirectMapping))
                {
                    fromMapped = Expression.Call(
                        Expression.Constant(this.aItemMapping.ResolvedMapping),
                        MappingMethods.Map(EnumerableReflection <TFrom> .ItemType, EnumerableReflection <TTo> .ItemType),
                        fromMapped
                        );
                }

                itemsAreMapEqual = Expression.Call(
                    Expression.Constant(EqualityComparerMethods.GetEqualityComparer(EnumerableReflection <TTo> .ItemType)),
                    EqualityComparerMethods.Equals(EnumerableReflection <TTo> .ItemType),
                    fromMapped,
                    toItem
                    );
            }

            if (this.aEqualityRules != null)
            {
                var(selectIdFrom, selectIdTo) = this.aEqualityRules.GetIdSelectors();
                itemsAreMapEqual = Expression.AndAlso(
                    Expression.Equal(
                        ExpressionHelper.Call(
                            selectIdFrom,
                            fromItem
                            ),
                        ExpressionHelper.Call(
                            selectIdTo,
                            toItem
                            )
                        ),
                    itemsAreMapEqual
                    );
            }

            return(itemsAreMapEqual);
        }
Beispiel #2
0
 private Expression AddPostprocess(Expression assignment, ParameterExpression to, Delegate postprocess, ParameterExpression parent)
 {
     if (postprocess != null)
     {
         return(Expression.Block(
                    assignment,
                    ExpressionHelper.Call(postprocess, parent, this.To.CreateGetterExpression(to))
                    ));
     }
     else
     {
         return(assignment);
     }
 }
        private Expression NewExpression(Expression from, Type type)
        {
            if (this.aFactoryFunction != null)
            {
                return(ExpressionHelper.Call(this.aFactoryFunction, from));
            }

            var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null);

            if (constructor == null)
            {
                throw new InvalidMappingException($"Cannot find constructor for type {typeof(TTo).FullName}");
            }

            return(Expression.New(constructor));
        }
Beispiel #4
0
        private Expression CreateChildPostprocessingExpression(Expression body)
        {
            if (this.aChildPostprocessing == null)
            {
                return(body);
            }

            var ret  = Expression.Parameter(typeof(TTo), "ret");
            var item = Expression.Parameter(EnumerableReflection <TTo> .ItemType, "item");

            return(Expression.Block(
                       new ParameterExpression[] { ret },

                       Expression.Assign(ret, body),
                       ExpressionHelper.ForEach(
                           item,
                           ret,
                           ExpressionHelper.Call(this.aChildPostprocessing, ret, item)
                           ),
                       ret
                       ));
        }
Beispiel #5
0
        public Expression CreateSynchronizationAssignmentExpression(ParameterExpression from, ParameterExpression to, Delegate postprocess, ParameterExpression parent)
        {
            IMappingWithSyncSupport mappingWithSync = this.Mapping.ResolvedMapping as IMappingWithSyncSupport;

            if (mappingWithSync == null)
            {
                return(this.CreateMappingAssignmentExpression(from, to, postprocess, parent));
            }

            ParameterExpression tempFromValue = Expression.Parameter(this.From.Type, "tempFrom");
            ParameterExpression tempToValue   = Expression.Parameter(this.To.Type, "tempTo");

            if (!this.To.Readable)
            {
                // TODO: ???
                throw new InvalidMappingException($"Cannot synchronize object with setter method mapping destination without any getter method defined for {this.To} member of {this.To.DeclaringType} type");
            }

            Expression synchronize = Expression.Call(
                Expression.Constant(mappingWithSync),
                MappingMethods.Synchronize(this.From.Type, this.To.Type),
                tempFromValue, tempToValue
                );

            if (mappingWithSync.SynchronizeCanChangeObject)
            {
                if (!this.To.Writable)
                {
                    throw new InvalidMappingException($"Cannot synchronize non writtable member {this.To} using mapping {mappingWithSync.GetType().Name}");
                }

                if (postprocess != null)
                {
                    var origToValue = Expression.Parameter(this.To.Type, "origTo");
                    var newToValue  = Expression.Parameter(this.To.Type, "newTo");

                    synchronize = Expression.Block(
                        new[] { origToValue, newToValue },
                        Expression.Assign(origToValue, tempToValue),
                        Expression.Assign(newToValue, synchronize),
                        Expression.IfThen(
                            ExpressionHelper.NotSame(origToValue, newToValue),
                            ExpressionHelper.Call(postprocess, parent, newToValue)
                            ),
                        this.To.CreateSetterExpression(
                            to,
                            newToValue
                            )
                        );
                }
                else
                {
                    synchronize = this.To.CreateSetterExpression(
                        to,
                        synchronize
                        );
                }
            }

            return(Expression.Block(
                       new ParameterExpression[] { tempFromValue, tempToValue },
                       Expression.Assign(tempFromValue, this.From.CreateGetterExpression(from)),
                       Expression.Assign(tempToValue, this.To.CreateGetterExpression(to)),
                       synchronize
                       ));
        }