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); }
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)); }
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 )); }
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 )); }