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); } }
public NullableWithSync(IMappingWithSyncSupport <TFrom, TTo> innerMapping) : base(innerMapping) { this.aInnerMapping = innerMapping; }
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 )); }
public PostprocessWithSync(IMappingWithSyncSupport <TFrom, TTo> innerMapping, Action <TFrom, TTo> postprocessDelegate) { this.aInnerMapping = innerMapping; this.aPostprocessDelegate = postprocessDelegate; }