/// <summary> /// Assign source member to a destination mapping, applying any custom mappings in the process. /// </summary> private void BuildMemberAssignmentExpressions( ParameterExpression source, ParameterExpression destination, ProposedMemberMapping member, List<Expression> expressions, ProposedTypeMapping typeMapping, CustomMapping customMapping = null ) { if (member.Ignored) { return; } Expression condition = null; if (member.Condition != null) { mapProcessor.ParametersToReplace.Add(new ExpressionTuple(member.Condition.Parameters.Single(), this.sourceParameter)); condition = member.Condition.Body; } var destMember = Expression.MakeMemberAccess(destination, member.DestinationMember); Expression assignSourceToDest = null; Expression customExpression = null; Expression assignConversionToDest = null; LambdaExpression conversionFunction = null; bool conversionReturnTypeSameAsParameterType = false; ParameterExpression conversionParameter = null; if (customMapping != null) { conversionFunction = customMapping.GetConversionFunction(member.SourceMember, member.DestinationMember); if (conversionFunction != null) { conversionParameter = conversionFunction.Parameters.Single(); conversionReturnTypeSameAsParameterType = conversionParameter.Type == conversionFunction.ReturnType; } } if (customMapping != null && (customExpression = customMapping.GetExpressionForMember(member.DestinationMember)) != null) { assignSourceToDest = Expression.Assign(destMember, customExpression); } else if (member.HierarchicalMapping != null) { var accessHierarchy = BuildHierarchicalExpression(source, member.HierarchicalMapping, null); if (destMember.Type.IsNullableValueType()) { accessHierarchy = Expression.Convert(accessHierarchy, destMember.Type); } assignSourceToDest = Expression.Assign(destMember, accessHierarchy); } else { Expression sourceExpression = Expression.MakeMemberAccess(source, member.SourceMember); bool usesConversionFunction = false; if (conversionFunction != null && !conversionReturnTypeSameAsParameterType) { ValidateConversionFunction(conversionFunction, conversionParameter, sourceExpression, destMember); this.mapProcessor.ParametersToReplace.Add(new ExpressionTuple(conversionParameter, sourceExpression)); sourceExpression = conversionFunction.Body; usesConversionFunction = true; } assignSourceToDest = AssignSimpleProperty(member, destMember, sourceExpression, typeMapping, usesConversionFunction); } if (conversionFunction != null && conversionReturnTypeSameAsParameterType) { this.mapProcessor.ParametersToReplace.Add(new ExpressionTuple(conversionParameter, destMember)); assignConversionToDest = Expression.Assign(destMember, conversionFunction.Body); } // If a condition to the mapping was specified if (condition != null) { if (assignConversionToDest != null) { assignSourceToDest = Expression.Block(assignSourceToDest, assignConversionToDest); } var ifCondition = Expression.IfThen(condition, assignSourceToDest); expressions.Add(ifCondition); } else { expressions.Add(assignSourceToDest); if (assignConversionToDest != null) { expressions.Add(assignConversionToDest); } } }
private void BuildMemberAssignmentExpressions(Expression sourceAccess, List<MemberBinding> memberBindings, ProposedMemberMapping member, CustomMapping customMapping) { if (member.Ignored) { return; } Expression customExpression; MemberAssignment bindSourceToDest; if (customMapping != null && (customExpression = customMapping.GetExpressionForMember(member.DestinationMember)) != null) { processor.ParametersToReplace.Add(new ProjectionExpressionTuple(customMapping.SourceParameter, sourceAccess)); bindSourceToDest = Expression.Bind(member.DestinationMember, customExpression); } else { Expression accessMember = Expression.MakeMemberAccess(sourceAccess, member.SourceMember); accessMember = HandleNullableValueTypes(member, accessMember); bindSourceToDest = Expression.Bind(member.DestinationMember, accessMember); } memberBindings.Add(bindSourceToDest); }
private void BuildSimpleTypeMappingExpressions(ParameterExpression source, ParameterExpression destination, ProposedMemberMapping member, List<Expression> expressions, List<ParameterExpression> newParams, CustomMapping customMapping = null) { Expression sourceExpression = Expression.PropertyOrField(source, member.SourceMember.Name); var destMember = Expression.PropertyOrField(destination, member.DestinationMember.Name); BinaryExpression assignSourceToDest; Expression customExpression; if (customMapping != null && (customExpression = customMapping.GetExpressionForMember(member.DestinationMember)) != null) { var visitor = new ParameterVisitor(customMapping.Parameter, source); customExpression = visitor.Visit(customExpression); assignSourceToDest = Expression.Assign(destMember, customExpression); } else { assignSourceToDest = Expression.Assign(destMember, sourceExpression); } expressions.Add(assignSourceToDest); }