private LambdaExpression GenerateObjectMapperExpression(MapRequest mapRequest, IObjectMapper mapperToUse, MapperConfiguration mapperConfiguration) { var destinationType = mapRequest.RequestedTypes.DestinationType; var source = Parameter(mapRequest.RequestedTypes.SourceType, "source"); var destination = Parameter(destinationType, "mapperDestination"); var context = Parameter(typeof(ResolutionContext), "context"); Expression fullExpression; if (mapperToUse == null) { var message = Constant("Missing type map configuration or unsupported mapping."); fullExpression = Block(Throw(New(ExceptionConstructor, message, Constant(null, typeof(Exception)), Constant(mapRequest.RequestedTypes))), Default(destinationType)); } else { var map = mapperToUse.MapExpression(mapperConfiguration, Configuration, null, ToType(source, mapRequest.RuntimeTypes.SourceType), ToType(destination, mapRequest.RuntimeTypes.DestinationType), context); var exception = Parameter(typeof(Exception), "ex"); fullExpression = TryCatch(ToType(map, destinationType), MakeCatchBlock(typeof(Exception), exception, Block( Throw(New(ExceptionConstructor, Constant("Error mapping types."), exception, Constant(mapRequest.RequestedTypes))), Default(destination.Type)), null)); } var nullCheckSource = TypeMapPlanBuilder.NullCheckSource(Configuration, source, destination, fullExpression); return(Lambda(nullCheckSource, source, destination, context)); }
internal static Expression MapCollectionExpression(this TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression, Func <Expression, Expression> conditionalExpression, Type ifInterfaceType, MapItem mapItem) { var passedDestination = Variable(destExpression.Type, "passedDestination"); var condition = conditionalExpression(passedDestination); var newExpression = Variable(passedDestination.Type, "collectionDestination"); var sourceElementType = TypeHelper.GetElementType(sourceExpression.Type); ParameterExpression itemParam; var itemExpr = mapItem(typeMapRegistry, configurationProvider, propertyMap, sourceExpression.Type, passedDestination.Type, contextExpression, out itemParam); var destinationElementType = itemExpr.Type; var destinationCollectionType = typeof(ICollection <>).MakeGenericType(destinationElementType); if (!destinationCollectionType.IsAssignableFrom(destExpression.Type)) { destinationCollectionType = typeof(IList); } var addMethod = destinationCollectionType.GetDeclaredMethod("Add"); var destination = propertyMap?.UseDestinationValue == true ? passedDestination : newExpression; var addItems = ForEach(sourceExpression, itemParam, Call(destination, addMethod, itemExpr)); var mapExpr = Block(addItems, destination); var allowNullCollections = propertyMap?.TypeMap.Profile.AllowNullCollections ?? configurationProvider.Configuration.AllowNullCollections; var ifNullExpr = allowNullCollections ? Constant(null, passedDestination.Type) : (Expression)newExpression; var clearMethod = destinationCollectionType.GetDeclaredMethod("Clear"); var checkNull = Block(new[] { newExpression, passedDestination }, Assign(passedDestination, destExpression), IfThenElse(condition ?? Constant(false), Block(Assign(newExpression, passedDestination), Call(newExpression, clearMethod)), Assign(newExpression, passedDestination.Type.NewExpr(ifInterfaceType))), Condition(Equal(sourceExpression, Constant(null)), ToType(ifNullExpr, passedDestination.Type), ToType(mapExpr, passedDestination.Type)) ); if (propertyMap != null) { return(checkNull); } var elementTypeMap = configurationProvider.ResolveTypeMap(sourceElementType, destinationElementType); if (elementTypeMap == null) { return(checkNull); } var checkContext = TypeMapPlanBuilder.CheckContext(elementTypeMap, contextExpression); if (checkContext == null) { return(checkNull); } return(Block(checkContext, checkNull)); }
public Expression MapExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) => TypeMapPlanBuilder.MapExpression(configurationProvider, profileMap, new TypePair(Nullable.GetUnderlyingType(sourceExpression.Type), destExpression.Type), Property(sourceExpression, sourceExpression.Type.GetDeclaredProperty("Value")), contextExpression, propertyMap, destExpression );
public Expression CreateExpression(TypeMapPlanBuilder builder) { var valueResolverExpression = ResolveSource(builder.Source, builder.Context); var sourceType = valueResolverExpression.Type; var resolvedValue = Variable(sourceType, "resolvedValue"); return(Block(new[] { resolvedValue }, Assign(resolvedValue, valueResolverExpression), builder.MapExpression(new TypePair(sourceType, DestinationType), resolvedValue))); }
internal static Expression MapItemExpr(this TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Type sourceType, Type destType, ParameterExpression itemParam, Expression contextParam) { var sourceElementType = TypeHelper.GetElementType(sourceType); var destElementType = TypeHelper.GetElementType(destType); var typePair = new TypePair(sourceElementType, destElementType); var itemExpr = TypeMapPlanBuilder.MapExpression(typeMapRegistry, configurationProvider, typePair, itemParam, contextParam, propertyMap); return(itemExpr); }
internal static Expression MapItemExpr(this IConfigurationProvider configurationProvider, ProfileMap profileMap, PropertyMap propertyMap, Type sourceType, Type destType, Expression contextParam, out ParameterExpression itemParam) { var sourceElementType = TypeHelper.GetElementType(sourceType); var destElementType = TypeHelper.GetElementType(destType); itemParam = Parameter(sourceElementType, "item"); var typePair = new TypePair(sourceElementType, destElementType); var itemExpr = TypeMapPlanBuilder.MapExpression(configurationProvider, profileMap, typePair, itemParam, contextParam, propertyMap); return ToType(itemExpr, destElementType); }
internal static Expression MapCollectionExpression(this TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression, Func <Expression, Expression> conditionalExpression, Type ifInterfaceType, MapItem mapItem) { var passedDestination = Expression.Variable(destExpression.Type, "passedDestination"); var condition = conditionalExpression(passedDestination); var newExpression = Expression.Variable(passedDestination.Type, "collectionDestination"); var sourceElementType = TypeHelper.GetElementType(sourceExpression.Type); var itemParam = Expression.Parameter(sourceElementType, "item"); var itemExpr = mapItem(typeMapRegistry, configurationProvider, propertyMap, sourceExpression.Type, passedDestination.Type, itemParam, contextExpression); var destinationElementType = itemExpr.Type; var destinationCollectionType = typeof(ICollection <>).MakeGenericType(destinationElementType); var clearMethod = destinationCollectionType.GetDeclaredMethod("Clear"); var cast = typeof(Enumerable).GetDeclaredMethod("Cast").MakeGenericMethod(itemParam.Type); var addMethod = destinationCollectionType.GetDeclaredMethod("Add"); var genericSource = sourceExpression.Type.IsGenericType() ? sourceExpression : Expression.Call(null, cast, sourceExpression); var destination = propertyMap?.UseDestinationValue == true ? passedDestination : newExpression; var addItems = ExpressionExtensions.ForEach(genericSource, itemParam, Expression.Call(destination, addMethod, itemExpr)); var mapExpr = Expression.Block(addItems, destination); var ifNullExpr = configurationProvider.Configuration.AllowNullCollections ? Expression.Constant(null, passedDestination.Type) : (Expression)newExpression; var checkNull = Expression.Block(new[] { newExpression, passedDestination }, Expression.Assign(passedDestination, destExpression), Expression.IfThenElse(condition ?? Expression.Constant(false), Expression.Block(Expression.Assign(newExpression, passedDestination), Expression.Call(newExpression, clearMethod)), Expression.Assign(newExpression, passedDestination.Type.NewExpr(ifInterfaceType))), Expression.Condition(Expression.Equal(sourceExpression, Expression.Constant(null)), ExpressionExtensions.ToType(ifNullExpr, passedDestination.Type), ExpressionExtensions.ToType(mapExpr, passedDestination.Type)) ); if (propertyMap != null) { return(checkNull); } var elementTypeMap = configurationProvider.ResolveTypeMap(sourceElementType, destinationElementType); if (elementTypeMap == null) { return(checkNull); } var checkContext = TypeMapPlanBuilder.CheckContext(elementTypeMap, contextExpression); if (checkContext == null) { return(checkNull); } return(Expression.Block(checkContext, checkNull)); }
public Expression MapExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) => Condition( Property(sourceExpression, sourceExpression.Type.GetDeclaredProperty("HasValue")), TypeMapPlanBuilder.MapExpression(configurationProvider, profileMap, new TypePair(Nullable.GetUnderlyingType(sourceExpression.Type), destExpression.Type), Property(sourceExpression, sourceExpression.Type.GetDeclaredProperty("Value")), contextExpression, propertyMap, destExpression ), DelegateFactory.GenerateConstructorExpression(destExpression.Type, profileMap) );
public Expression BuildExpression(TypeMapPlanBuilder builder) { if (!CanResolve) return null; var ctorArgs = CtorParams.Select(p => p.CreateExpression(builder)); ctorArgs = ctorArgs.Zip(Ctor.GetParameters(), (exp, pi) => exp.Type == pi.ParameterType ? exp : Convert(exp, pi.ParameterType)) .ToArray(); var newExpr = New(Ctor, ctorArgs); return newExpr; }
public Expression CreateExpression(TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, ParameterExpression ctxtParam, ref ParameterExpression parameterContext) { if (CustomExpression != null) { return(CustomExpression.ConvertReplaceParameters(srcParam).IfNotNull()); } if (CustomValueResolver != null) { return(Invoke(Constant(CustomValueResolver), srcParam, ctxtParam)); } if (!SourceMembers.Any() && Parameter.IsOptional) { return(Constant(Parameter.GetDefaultValue())); } if (typeMapRegistry.GetTypeMap(new TypePair(SourceType, DestinationType)) == null && Parameter.IsOptional) { return(Constant(Parameter.GetDefaultValue())); } var valueResolverExpr = SourceMembers.Aggregate( (Expression)srcParam, (inner, getter) => getter.MemberInfo is MethodInfo ? getter.MemberInfo.IsStatic() ? Call(null, (MethodInfo)getter.MemberInfo, inner) : (Expression)Call(inner, (MethodInfo)getter.MemberInfo) : MakeMemberAccess(getter.MemberInfo.IsStatic() ? null : inner, getter.MemberInfo) ); valueResolverExpr = valueResolverExpr.IfNotNull(); if ((SourceType.IsEnumerableType() && SourceType != typeof(string)) || typeMapRegistry.GetTypeMap(new TypePair(SourceType, DestinationType)) != null || !DestinationType.IsAssignableFrom(SourceType)) { /* * var value = context.Mapper.Map(result, null, sourceType, destinationType, context); */ return(TypeMapPlanBuilder.ContextMap(valueResolverExpr, Default(DestinationType), DestinationType, ref parameterContext)); } return(valueResolverExpr); }
public Expression BuildExpression(TypeMapPlanBuilder builder) { if (!CanResolve) { return(null); } var ctorArgs = CtorParams.Select(p => p.CreateExpression(builder)); ctorArgs = ctorArgs.Zip(Ctor.GetParameters(), (exp, pi) => exp.Type == pi.ParameterType ? exp : Convert(exp, pi.ParameterType)) .ToArray(); var newExpr = New(Ctor, ctorArgs); return(newExpr); }
internal static Expression MapKeyPairValueExpr(this TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Type sourceType, Type destType, ParameterExpression itemParam, Expression contextParam) { var sourceElementTypes = TypeHelper.GetElementTypes(sourceType, ElemntTypeFlags.BreakKeyValuePair); var destElementTypes = TypeHelper.GetElementTypes(destType, ElemntTypeFlags.BreakKeyValuePair); var typePairKey = new TypePair(sourceElementTypes[0], destElementTypes[0]); var typePairValue = new TypePair(sourceElementTypes[1], destElementTypes[1]); var sourceElementType = TypeHelper.GetElementType(sourceType); var destElementType = TypeHelper.GetElementType(destType); var keyExpr = TypeMapPlanBuilder.MapExpression(typeMapRegistry, configurationProvider, typePairKey, Expression.Property(itemParam, "Key"), contextParam, propertyMap); var valueExpr = TypeMapPlanBuilder.MapExpression(typeMapRegistry, configurationProvider, typePairValue, Expression.Property(itemParam, "Value"), contextParam, propertyMap); var keyPair = Expression.New(destElementType.GetConstructors().First(), keyExpr, valueExpr); return(keyPair); }
internal static Expression MapKeyPairValueExpr(this IConfigurationProvider configurationProvider, ProfileMap profileMap, PropertyMap propertyMap, Type sourceType, Type destType, Expression contextParam, out ParameterExpression itemParam) { var sourceElementTypes = TypeHelper.GetElementTypes(sourceType, ElementTypeFlags.BreakKeyValuePair); var destElementTypes = TypeHelper.GetElementTypes(destType, ElementTypeFlags.BreakKeyValuePair); var typePairKey = new TypePair(sourceElementTypes[0], destElementTypes[0]); var typePairValue = new TypePair(sourceElementTypes[1], destElementTypes[1]); var sourceElementType = typeof(KeyValuePair<,>).MakeGenericType(sourceElementTypes); itemParam = Parameter(sourceElementType, "item"); var destElementType = typeof(KeyValuePair<,>).MakeGenericType(destElementTypes); var keyExpr = TypeMapPlanBuilder.MapExpression(configurationProvider, profileMap, typePairKey, Property(itemParam, "Key"), contextParam, propertyMap); var valueExpr = TypeMapPlanBuilder.MapExpression(configurationProvider, profileMap, typePairValue, Property(itemParam, "Value"), contextParam, propertyMap); var keyPair = New(destElementType.GetConstructors().First(), keyExpr, valueExpr); return keyPair; }
public void Seal(IConfigurationProvider configurationProvider, HashSet <TypeMap> visitedTypeMaps = null) { if (_sealed) { return; } _sealed = true; foreach (var inheritedTypeMap in _inheritedTypeMaps) { ApplyInheritedTypeMap(inheritedTypeMap); } _orderedPropertyMaps = _propertyMaps .Union(_inheritedMaps) .OrderBy(map => map.MappingOrder).ToArray(); MapExpression = new TypeMapPlanBuilder(configurationProvider, this).CreateMapperLambda(visitedTypeMaps); }
public void Seal(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider) { if (_sealed) { return; } foreach (var inheritedTypeMap in _inheritedTypeMaps) { ApplyInheritedTypeMap(inheritedTypeMap); } _orderedPropertyMaps = _propertyMaps .Union(_inheritedMaps) .OrderBy(map => map.MappingOrder).ToArray(); MapExpression = TypeMapPlanBuilder.BuildMapperFunc(this, configurationProvider, typeMapRegistry); _sealed = true; }
public void Seal(IConfigurationProvider configurationProvider, Stack <TypeMap> typeMapsPath = null) { if (_sealed) { return; } _sealed = true; foreach (var inheritedTypeMap in _inheritedTypeMaps) { ApplyInheritedTypeMap(inheritedTypeMap); } _orderedPropertyMaps = _propertyMaps .Union(_inheritedMaps) .OrderBy(map => map.MappingOrder).ToArray(); MapExpression = new TypeMapPlanBuilder(configurationProvider, this).CreateMapperLambda(typeMapsPath); DebugHelpers.LogExpression(MapExpression, "MapExpression"); }
internal static Expression MapCollectionExpression(this TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression, Func <Expression, Expression> conditionalExpression, Type ifInterfaceType, MapItem mapItem) { var passedDestination = Variable(destExpression.Type, "passedDestination"); var newExpressionValue = passedDestination.NewIfConditionFails(conditionalExpression, ifInterfaceType); var newExpression = Variable(newExpressionValue.Type, "collectionDestination"); var sourceElementType = TypeHelper.GetElementType(sourceExpression.Type); var itemParam = Parameter(sourceElementType, "item"); var itemExpr = mapItem(typeMapRegistry, configurationProvider, propertyMap, sourceExpression.Type, passedDestination.Type, itemParam, contextExpression); var blockExpressions = new List <Expression>(); var blockVariables = new List <ParameterExpression> { newExpression, passedDestination }; Expression destination; var destinationElementType = itemExpr.Type; var destinationCollectionType = typeof(ICollection <>).MakeGenericType(destinationElementType); var clearMethod = destinationCollectionType.GetDeclaredMethod("Clear"); if (passedDestination.Type.IsCollectionType()) { if (propertyMap == null) { destination = newExpression; blockExpressions.Add(IfThenElse(NotEqual(passedDestination, Constant(null)), Call(passedDestination, clearMethod), Assign(destination, newExpression) )); } else if (propertyMap.UseDestinationValue) { destination = passedDestination; blockExpressions.Add(Call(passedDestination, clearMethod)); } else { destination = newExpression; } } else { destination = newExpression; } var cast = typeof(Enumerable).GetTypeInfo().DeclaredMethods.First(_ => _.Name == "Cast").MakeGenericMethod(itemParam.Type); var addMethod = destinationCollectionType.GetDeclaredMethod("Add"); var genericSource = sourceExpression.Type.GetTypeInfo().IsGenericType ? sourceExpression : Call(null, cast, sourceExpression); blockExpressions.Add(ForEach(genericSource, itemParam, Call( destination, addMethod, itemExpr))); blockExpressions.Add(destination); var mapExpr = Block(blockExpressions); var ifNullExpr = configurationProvider.Configuration.AllowNullCollections ? Constant(null, passedDestination.Type) : (Expression)newExpression; var checkNull = Block(blockVariables, Assign(passedDestination, destExpression), Assign(newExpression, newExpressionValue), Condition(Equal(sourceExpression, Constant(null)), ToType(ifNullExpr, passedDestination.Type), ToType(mapExpr, passedDestination.Type)) ); if (propertyMap != null) { return(checkNull); } var elementTypeMap = configurationProvider.ResolveTypeMap(sourceElementType, destinationElementType); if (elementTypeMap == null) { return(checkNull); } var checkContext = TypeMapPlanBuilder.CheckContext(elementTypeMap, contextExpression); if (checkContext == null) { return(checkNull); } return(Block(checkContext, checkNull)); }
public void Seal(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider) { if(_sealed) { return; } _sealed = true; foreach (var inheritedTypeMap in _inheritedTypeMaps) { ApplyInheritedTypeMap(inheritedTypeMap); } _orderedPropertyMaps = _propertyMaps .Union(_inheritedMaps) .OrderBy(map => map.MappingOrder).ToArray(); MapExpression = new TypeMapPlanBuilder(configurationProvider, typeMapRegistry, this).CreateMapperLambda(); }