public override IEnumerable<Expression> BuildMapping(MappingBuilderContext context) { var sourceMember = context.Rewrite(Source); var destinationMember = context.Rewrite(Destination); var sourceMemberType = ExpressionHelper.GetMemberTypeOrCollectionElementType(Source); var destMemberType = ExpressionHelper.GetMemberTypeOrCollectionElementType(Destination); if (Converter != null) { var converterIndex = context.Converters.ToList().IndexOf(Converter); var sourcePropertyPathFormat = sourceMember.ToPathWithFormatting(); var destPropertyPathFormat = destinationMember.ToPathWithFormatting(); var converterType = typeof(IConverter<,>).MakeGenericType(sourceMemberType, destMemberType); var conversionResultType = typeof(ConversionResult<,>).MakeGenericType(sourceMemberType, destMemberType); var converterVar = Expression.Parameter(converterType, "converter"); var conversionResult = Expression.Parameter(conversionResultType, "conversionResult"); var destValueVar = Expression.Parameter(typeof(object), "destValue"); yield return Expression.Block( new ParameterExpression[] { converterVar, destValueVar, conversionResult }, Expression.Assign( converterVar, Expression.Convert( Expression.ArrayIndex( Expression.Property(context.ContextParameter, nameof(MappingContext.Converters)), Expression.Constant(converterIndex)), converterType)), Expression.Assign( conversionResult, Expression.Call( converterVar, nameof(IConverter<object, object>.Convert), new Type[] { }, sourceMember)), Expression.IfThenElse( Expression.Property(conversionResult, nameof(ConversionResult<object, object>.IsConvertedSuccessfully)), MakeAssignment( context, destinationMember, Expression.Property(conversionResult, nameof(ConversionResult<object, object>.ConvertedValue))), AddConversionError(context, sourcePropertyPathFormat, destPropertyPathFormat, conversionResult, sourceMember))); } else { if (!destMemberType.IsAssignableFrom(sourceMemberType)) sourceMember = Expression.Convert(sourceMember, destMemberType); yield return MakeAssignment(context, destinationMember, sourceMember); } }
public override IEnumerable<Expression> BuildMapping(MappingBuilderContext context) { yield return Expression.Block( Expression.IfThen( BuildSourceNullChecksCondition(context), Expression.Block( Expression.IfThen( Expression.Equal(context.Rewrite(Member), Expression.Constant(null)), Expression.Assign(context.Rewrite(Member), Expression.New(Member.Type))), ChildMapping(context) ))); }
public override IEnumerable<Expression> BuildMapping(MappingBuilderContext context) { var index = context.CreateIteratorVariable(); var source = FindChildSource(Children.First()); var srcIndexer = ExpressionHelper.TrimIndexer(source, Indexer); var breakLabel = Expression.Label(); var nullCheckCondition = BuildSourceNullChecksCondition(context); context.IndexerParameters.Push(index); var block = Expression.IfThen( nullCheckCondition, Expression.Block( new[] { index }, Expression.Assign(index, Expression.Constant(0)), Expression.Assign(context.Rewrite(Member), Expression.New(GetMemberType())), Expression.Loop( Expression.Block( Expression.IfThenElse( Expression.LessThan(index, ExpressionHelper.GetLengthExpressionFromIndexer(context.Rewrite(srcIndexer))), Expression.IfThenElse( Expression.NotEqual(context.Rewrite(srcIndexer), Expression.Constant(null)), Expression.Block( Expression.Call( context.Rewrite(Member), "Add", new Type[] { }, ExpressionEx.NewOrDefault(GetCollectionElementType())), ChildMapping(context)), Expression.Call( context.Rewrite(Member), "Add", new Type[] { }, Expression.Default(GetCollectionElementType()))), Expression.Break(breakLabel)), Expression.Assign(index, Expression.Add(index, Expression.Constant(1)))), breakLabel))); context.IndexerParameters.Pop(); return new[] { block }; }
protected Expression BuildSourceNullChecksCondition(MappingBuilderContext context) { var common = Sources() .Select(src => new CommonPart { Source = src, SourceParts = ExpressionParser.SplitExpression(src) .Where(a => !String.IsNullOrEmpty(a.Path)) .Where(a => !a.IsMostRightPart) .Where(a => ExpressionHelper.GetIndexerCount(a.Member) <= context.IndexerParameters.Count) .ToArray() }) .ToArray(); var commonMembers = new List<Expression>(); var index = 0; while (true) { if (common.Any(a => a.SourceParts.Length <= index)) break; var parts = common.Select(c => c.SourceParts[index]) .ToArray(); if (parts.All(p => p.Path == parts[0].Path)) { commonMembers.Add(parts[0].Member); if (parts[0].Indexer != null && ExpressionHelper.GetIndexerCount(parts[0].Indexer) <= context.IndexerParameters.Count) commonMembers.Add(parts[0].Indexer); index++; } else break; } var condition = commonMembers.Aggregate<Expression, Expression>( Expression.Constant(true), (acc, expr) => Expression.AndAlso(acc, Expression.NotEqual(context.Rewrite(expr), Expression.Constant(null)))); return condition; }