private IEnumerator <TItemTo> EnumerateWithSync(IMappingWithSyncSupport <TItemFrom, TItemTo> mappingWithSync)
        {
            var index = this.aTo.ToDictionary(this.aSelectIdTo);

            foreach (TItemFrom itemFrom in this.aFrom)
            {
                TItemTo itemTo;
                if (index.TryGetValue(this.aSelectIdFrom(itemFrom), out itemTo))
                {
                    itemTo = mappingWithSync.Synchronize(itemFrom, itemTo);
                }
                else
                {
                    itemTo = mappingWithSync.Map(itemFrom);
                }

                yield return(itemTo);
            }
        }
Example #2
0
 public NullableWithSync(IMappingWithSyncSupport <TFrom, TTo> innerMapping)
     : base(innerMapping)
 {
     this.aInnerMapping = innerMapping;
 }
Example #3
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
                       ));
        }
Example #4
0
 public PostprocessWithSync(IMappingWithSyncSupport <TFrom, TTo> innerMapping, Action <TFrom, TTo> postprocessDelegate)
 {
     this.aInnerMapping        = innerMapping;
     this.aPostprocessDelegate = postprocessDelegate;
 }