public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) => typeMapRegistry.MapCollectionExpression(configurationProvider, propertyMap, sourceExpression, destExpression, contextExpression, CollectionMapperExtensions.IfNotNull, typeof(Dictionary<,>), CollectionMapperExtensions.MapItemExpr);
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { Expression<Func<DestinationType>> expr = () => new DestinationType(); return expr.Body; }
private static Expression CreateDestinationFunc( TypeMap typeMap, TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, ParameterExpression destParam, ParameterExpression ctxtParam) { var newDestFunc = ToType(CreateNewDestinationFunc(typeMap, typeMapRegistry, srcParam, ctxtParam), typeMap.DestinationTypeToUse); var getDest = typeMap.DestinationTypeToUse.GetTypeInfo().IsValueType ? newDestFunc : Coalesce(destParam, newDestFunc); Expression destinationFunc = Assign(destParam, getDest); if (typeMap.PreserveReferences) { var dest = Variable(typeof (object), "dest"); Expression valueBag = Property(ctxtParam, "InstanceCache"); var set = Assign(Property(valueBag, "Item", srcParam), dest); var setCache = IfThen(NotEqual(srcParam, Constant(null)), set); destinationFunc = Block(new[] {dest}, Assign(dest, destinationFunc), setCache, dest); } return destinationFunc; }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { var listType = typeof(List<>).MakeGenericType(TypeHelper.GetElementType(destExpression.Type)); var list = typeMapRegistry.MapCollectionExpression(configurationProvider, propertyMap, sourceExpression, Default(listType), contextExpression, _ => Constant(false), typeof(List<>), CollectionMapperExtensions.MapItemExpr); var dest = Variable(listType, "dest"); return Block(new[] { dest }, Assign(dest, list), Condition(NotEqual(dest, Default(listType)), New(destExpression.Type.GetConstructors().First(), dest), Default(destExpression.Type))); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { return Condition(Equal(sourceExpression, Default(sourceExpression.Type)), Constant(null, typeof(string)), Call(sourceExpression, typeof(object).GetDeclaredMethod("ToString"))); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { var listType = typeof(List<>).MakeGenericType(TypeHelper.GetElementType(destExpression.Type)); return typeMapRegistry.MapCollectionExpression(configurationProvider, propertyMap, sourceExpression, Expression.Default(listType), contextExpression, IfEditableList, typeof(List<>), CollectionMapperExtensions.MapItemExpr); }
public TypeMapPlanBuilder(IConfigurationProvider configurationProvider, TypeMapRegistry typeMapRegistry, TypeMap typeMap) { _configurationProvider = configurationProvider; _typeMapRegistry = typeMapRegistry; _typeMap = typeMap; _source = Parameter(typeMap.SourceType, "src"); _initialDestination = Parameter(typeMap.DestinationTypeToUse, "dest"); _context = Parameter(typeof(ResolutionContext), "ctxt"); _destination = Variable(_initialDestination.Type, "typeMapDestination"); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { var toStringCall = Call(sourceExpression, typeof(object).GetDeclaredMethod("ToString")); if(sourceExpression.Type.IsValueType()) { return toStringCall; } return Condition(Equal(sourceExpression, Constant(null)), Constant(null, typeof(string)), toStringCall); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { Type destElementType = TypeHelper.GetElementType(destExpression.Type); Expression<Action> expr = () => Array.Copy(null, null, 0); var copyMethod = ((MethodCallExpression) expr.Body).Method; var valueIfNullExpr = configurationProvider.Configuration.AllowNullCollections ? (Expression) Constant(null, destExpression.Type) : NewArrayBounds(destElementType, Constant(0)); var dest = Parameter(destExpression.Type, "destArray"); var sourceLength = Parameter(typeof(int), "sourceLength"); var lengthProperty = typeof(Array).GetDeclaredProperty("Length"); var mapExpr = Block( new[] {dest, sourceLength}, Assign(sourceLength, Property(sourceExpression, lengthProperty)), Assign(dest, NewArrayBounds(destElementType, sourceLength)), Call(copyMethod, sourceExpression, dest, sourceLength), dest ); return Condition(Equal(sourceExpression, Constant(null)), valueIfNullExpr, mapExpr); }
private static Expression CreatePropertyMapFunc( PropertyMap propertyMap, IConfigurationProvider configurationProvider, TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, ParameterExpression destParam, ParameterExpression ctxtParam) { var destMember = MakeMemberAccess(destParam, propertyMap.DestinationProperty.MemberInfo); Expression getter; var pi = propertyMap.DestinationProperty.MemberInfo as PropertyInfo; if (pi != null && pi.GetGetMethod(true) == null) { getter = Default(propertyMap.DestinationPropertyType); } else { getter = destMember; } var destValueExpr = propertyMap.UseDestinationValue ? getter : Default(propertyMap.DestinationPropertyType); var valueResolverExpr = BuildValueResolverFunc(propertyMap, typeMapRegistry, srcParam, getter, ctxtParam); if (propertyMap.SourceType != null && propertyMap.DestinationPropertyType != null) { var typePair = new TypePair(propertyMap.SourceType, propertyMap.DestinationPropertyType); var typeMap = configurationProvider.ResolveTypeMap(typePair); if (typeMap != null && (typeMap.TypeConverterType != null || typeMap.CustomMapper != null)) { if (!typeMap.Sealed) { typeMap.Seal(typeMapRegistry, configurationProvider); } valueResolverExpr = typeMap.MapExpression.ReplaceParameters(valueResolverExpr, destValueExpr, ctxtParam); } else { var match = configurationProvider.GetMappers().FirstOrDefault(m => m.IsMatch(typePair)); var expressionMapper = match; if (expressionMapper != null) { valueResolverExpr = expressionMapper.MapExpression(typeMapRegistry, configurationProvider, propertyMap, valueResolverExpr, destValueExpr, ctxtParam); } else { valueResolverExpr = SetMap(propertyMap, valueResolverExpr, destValueExpr, ctxtParam); } } } else { valueResolverExpr = SetMap(propertyMap, valueResolverExpr, destValueExpr, ctxtParam); } if (propertyMap.Condition != null) { valueResolverExpr = Condition( propertyMap.Condition.ConvertReplaceParameters( srcParam, destParam, ToType(valueResolverExpr, propertyMap.Condition.Parameters[2].Type), ToType(getter, propertyMap.Condition.Parameters[2].Type), ctxtParam ), ToType(valueResolverExpr, propertyMap.DestinationPropertyType), getter ); } Expression mapperExpr; if (propertyMap.DestinationProperty.MemberInfo is FieldInfo) { mapperExpr = propertyMap.SourceType != propertyMap.DestinationPropertyType ? Assign(destMember, ToType(valueResolverExpr, propertyMap.DestinationPropertyType)) : Assign(getter, valueResolverExpr); } else { var setter = ((PropertyInfo)propertyMap.DestinationProperty.MemberInfo).GetSetMethod(true); if (setter == null) { mapperExpr = valueResolverExpr; } else { mapperExpr = Assign(destMember, propertyMap.SourceType != propertyMap.DestinationPropertyType ? ToType(valueResolverExpr, propertyMap.DestinationPropertyType) : valueResolverExpr); } } if (propertyMap.PreCondition != null) { mapperExpr = IfThen( propertyMap.PreCondition.ConvertReplaceParameters(srcParam, ctxtParam), mapperExpr ); } return(mapperExpr); }
private static Expression CreateNewDestinationFunc( TypeMap typeMap, TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, ParameterExpression ctxtParam) { if (typeMap.DestinationCtor != null) return typeMap.DestinationCtor.ReplaceParameters(srcParam, ctxtParam); if (typeMap.ConstructDestinationUsingServiceLocator) return Call(MakeMemberAccess(ctxtParam, typeof (ResolutionContext).GetProperty("Options")), typeof (MappingOperationOptions).GetMethod("CreateInstance") .MakeGenericMethod(typeMap.DestinationTypeToUse) ); if (typeMap.ConstructorMap?.CanResolve == true) return typeMap.ConstructorMap.BuildExpression(typeMapRegistry, srcParam, ctxtParam); #if NET45 if (typeMap.DestinationTypeToUse.IsInterface()) { var ctor = Call(Constant(ObjectCreator.DelegateFactory), typeof(DelegateFactory).GetMethod("CreateCtor", new[] { typeof(Type) }), Call(New(typeof(ProxyGenerator)), typeof(ProxyGenerator).GetMethod("GetProxyType"), Constant(typeMap.DestinationTypeToUse))); // We're invoking a delegate here return Invoke(ctor); } #endif if (typeMap.DestinationTypeToUse.IsAbstract()) return Constant(null); if (typeMap.DestinationTypeToUse.IsGenericTypeDefinition()) return Constant(null); return DelegateFactory.GenerateConstructorExpression(typeMap.DestinationTypeToUse); }
private static Expression CreateAssignmentFunc( TypeMap typeMap, IConfigurationProvider configurationProvider, TypeMapRegistry registry, ParameterExpression srcParam, ParameterExpression destParam, ParameterExpression ctxtParam, Expression destinationFunc, ParameterExpression destination, bool constructorMapping) { var actions = new List<Expression>(); foreach(var propertyMap in typeMap.GetPropertyMaps()) { if(!propertyMap.CanResolveValue()) { continue; } var property = TryPropertyMap(propertyMap, configurationProvider, registry, srcParam, destination, ctxtParam); if(constructorMapping && typeMap.ConstructorParameterMatches(propertyMap.DestinationProperty.Name)) { property = IfThen(NotEqual(destParam, Expression.Constant(null)), property); } actions.Add(property); } foreach (var beforeMapAction in typeMap.BeforeMapActions) { actions.Insert(0, beforeMapAction.ReplaceParameters(srcParam, destination, ctxtParam)); } actions.Insert(0, destinationFunc); if (typeMap.MaxDepth > 0) { actions.Insert(0, Call(ctxtParam, ((MethodCallExpression)IncTypeDepthInfo.Body).Method, Constant(typeMap.Types))); } actions.AddRange( typeMap.AfterMapActions.Select( afterMapAction => afterMapAction.ReplaceParameters(srcParam, destination, ctxtParam))); if (typeMap.MaxDepth > 0) { actions.Add(Call(ctxtParam, ((MethodCallExpression)DecTypeDepthInfo.Body).Method, Constant(typeMap.Types))); } actions.Add(destination); return Block(actions); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { var implicitOperator = GetImplicitConversionOperator(new TypePair(sourceExpression.Type, destExpression.Type)); return Expression.Call(null, implicitOperator, sourceExpression); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { var implicitOperator = GetImplicitConversionOperator(new TypePair(sourceExpression.Type, destExpression.Type)); return(Expression.Call(null, implicitOperator, sourceExpression)); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { return(Expression.Call(null, MapMethodInfo.MakeGenericMethod(Nullable.GetUnderlyingType(sourceExpression.Type), destExpression.Type), sourceExpression, destExpression, contextExpression)); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, Expression sourceExpression, Expression destExpression, Expression contextExpression) { return(Expression.Condition(Expression.Equal(sourceExpression, Expression.Default(sourceExpression.Type)), Expression.Constant(null, typeof(string)), Expression.Call(sourceExpression, typeof(object).GetMethod("ToString")))); }
private static Expression BuildValueResolverFunc(PropertyMap propertyMap, TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, ParameterExpression destParam, Expression destValueExpr, ParameterExpression ctxtParam) { Expression valueResolverFunc; var valueResolverConfig = propertyMap.ValueResolverConfig; var typeMap = propertyMap.TypeMap; if (valueResolverConfig != null) { Expression ctor; Type resolverType; if (valueResolverConfig.Instance != null) { ctor = Constant(valueResolverConfig.Instance); resolverType = valueResolverConfig.Instance.GetType(); } else { ctor = Call(MakeMemberAccess(ctxtParam, typeof (ResolutionContext).GetDeclaredProperty("Options")), typeof (IMappingOperationOptions).GetDeclaredMethod("CreateInstance") .MakeGenericMethod(valueResolverConfig.Type) ); resolverType = valueResolverConfig.Type; } if (valueResolverConfig.SourceMember != null) { var sourceMember = valueResolverConfig.SourceMember.ReplaceParameters(srcParam); var iResolverType = resolverType.GetTypeInfo() .ImplementedInterfaces.First(t => t.ImplementsGenericInterface(typeof(IMemberValueResolver<,,,>))); var sourceResolverParam = iResolverType.GetGenericArguments()[0]; var destResolverParam = iResolverType.GetGenericArguments()[1]; var sourceMemberResolverParam = iResolverType.GetGenericArguments()[2]; var destMemberResolverParam = iResolverType.GetGenericArguments()[3]; valueResolverFunc = ToType(Call(ToType(ctor, resolverType), resolverType.GetDeclaredMethod("Resolve"), ToType(srcParam, sourceResolverParam), ToType(destParam, destResolverParam), ToType(sourceMember, sourceMemberResolverParam), ToType(destValueExpr, destMemberResolverParam), ctxtParam), propertyMap.DestinationPropertyType); } else if (valueResolverConfig.SourceMemberName != null) { var sourceMember = MakeMemberAccess(srcParam, typeMap.SourceType.GetFieldOrProperty(valueResolverConfig.SourceMemberName)); var iResolverType = resolverType.GetTypeInfo() .ImplementedInterfaces.First(t => t.ImplementsGenericInterface(typeof(IMemberValueResolver<,,,>))); var sourceResolverParam = iResolverType.GetGenericArguments()[0]; var destResolverParam = iResolverType.GetGenericArguments()[1]; var sourceMemberResolverParam = iResolverType.GetGenericArguments()[2]; var destMemberResolverParam = iResolverType.GetGenericArguments()[3]; valueResolverFunc = ToType(Call(ToType(ctor, resolverType), resolverType.GetDeclaredMethod("Resolve"), ToType(srcParam, sourceResolverParam), ToType(destParam, destResolverParam), ToType(sourceMember, sourceMemberResolverParam), ToType(destValueExpr, destMemberResolverParam), ctxtParam), propertyMap.DestinationPropertyType); } else { var iResolverType = resolverType.GetTypeInfo() .ImplementedInterfaces.First(t => t.IsGenericType() && t.GetGenericTypeDefinition() == typeof(IValueResolver<,,>)); var sourceResolverParam = iResolverType.GetGenericArguments()[0]; var destResolverParam = iResolverType.GetGenericArguments()[1]; var destMemberResolverParam = iResolverType.GetGenericArguments()[2]; valueResolverFunc = ToType(Call(ToType(ctor, resolverType), iResolverType.GetDeclaredMethod("Resolve"), ToType(srcParam, sourceResolverParam), ToType(destParam, destResolverParam), ToType(destValueExpr, destMemberResolverParam), ctxtParam), propertyMap.DestinationPropertyType); } } else if (propertyMap.CustomResolver != null) { valueResolverFunc = propertyMap.CustomResolver.ReplaceParameters(srcParam, destParam, destValueExpr, ctxtParam); } else if (propertyMap.CustomExpression != null) { var nullCheckedExpression = propertyMap.CustomExpression.ReplaceParameters(srcParam).IfNotNull(propertyMap.DestinationPropertyType); valueResolverFunc = TryCatch(nullCheckedExpression, Catch(typeof(NullReferenceException), Default(nullCheckedExpression.Type))); } else if (propertyMap.SourceMembers.Any() && propertyMap.SourceType != null ) { var last = propertyMap.SourceMembers.Last(); var pi = last as PropertyInfo; if (pi != null && pi.GetGetMethod(true) == null) { valueResolverFunc = Default(last.GetMemberType()); } else { valueResolverFunc = propertyMap.SourceMembers.Aggregate( (Expression) srcParam, (inner, getter) => getter is MethodInfo ? getter.IsStatic() ? Call(null, (MethodInfo) getter, inner) : (Expression) Call(inner, (MethodInfo) getter) : MakeMemberAccess(getter.IsStatic() ? null : inner, getter) ); valueResolverFunc = valueResolverFunc.IfNotNull(propertyMap.DestinationPropertyType); } } else if (propertyMap.SourceMember != null) { valueResolverFunc = MakeMemberAccess(srcParam, propertyMap.SourceMember); } else { valueResolverFunc = Throw(Constant(new Exception("I done blowed up"))); } if (propertyMap.DestinationPropertyType == typeof (string) && valueResolverFunc.Type != typeof (string) && typeMapRegistry.GetTypeMap(new TypePair(valueResolverFunc.Type, propertyMap.DestinationPropertyType)) == null) { valueResolverFunc = Call(valueResolverFunc, typeof(object).GetDeclaredMethod("ToString", new Type[0])); } if (propertyMap.NullSubstitute != null) { Expression value = Constant(propertyMap.NullSubstitute); if (propertyMap.NullSubstitute.GetType() != propertyMap.DestinationPropertyType) value = ToType(value, propertyMap.DestinationPropertyType); valueResolverFunc = MakeBinary(ExpressionType.Coalesce, valueResolverFunc, value); } else if (!typeMap.Profile.AllowNullDestinationValues) { var toCreate = propertyMap.SourceType ?? propertyMap.DestinationPropertyType; if (!toCreate.GetTypeInfo().IsValueType) { valueResolverFunc = MakeBinary(ExpressionType.Coalesce, valueResolverFunc, ToType(Call( typeof (ObjectCreator).GetDeclaredMethod("CreateNonNullValue"), Constant(toCreate) ), propertyMap.SourceType)); } } return valueResolverFunc; }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, Expression sourceExpression, Expression destExpression, Expression contextExpression) { return(Expression.Call(null, MapMethodInfo.MakeGenericMethod(TypeHelper.GetElementType(sourceExpression.Type), TypeHelper.GetElementType(destExpression.Type)), sourceExpression, destExpression, contextExpression)); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { return Expression.Call(null, MapMethodInfo, sourceExpression); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) => typeMapRegistry.MapCollectionExpression(configurationProvider, propertyMap, sourceExpression, destExpression, contextExpression, CollectionMapperExtensions.IfNotNull, typeof(List <>), CollectionMapperExtensions.MapItemExpr);
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 newExpr = destExpression.NewIfConditionFails(conditionalExpression, ifInterfaceType); var itemParam = Parameter(TypeHelper.GetElementType(sourceExpression.Type), "item"); var itemExpr = mapItem(typeMapRegistry, configurationProvider, propertyMap, sourceExpression.Type, destExpression.Type, itemParam, contextExpression); var blockExprs = new List <Expression>(); var blockParams = new List <ParameterExpression>(); var dest = destExpression; if (destExpression.Type.IsCollectionType()) { if (propertyMap == null) { var destParam = Parameter(newExpr.Type, "d"); blockParams.Add(destParam); blockExprs.Add(Assign(destParam, destExpression)); dest = destParam; var clearMethod = typeof(ICollection <>).MakeGenericType(TypeHelper.GetElementType(destExpression.Type)).GetMethod("Clear"); blockExprs.Add(IfThenElse(NotEqual(destExpression, Constant(null)), Call(destExpression, clearMethod), Assign(destParam, newExpr) )); } else if (propertyMap.UseDestinationValue) { var clearMethod = typeof(ICollection <>).MakeGenericType(TypeHelper.GetElementType(destExpression.Type)).GetMethod("Clear"); blockExprs.Add(Call(destExpression, clearMethod)); } else { var destParam = Parameter(newExpr.Type, "d"); blockParams.Add(destParam); blockExprs.Add(Assign(destParam, newExpr)); dest = destParam; } } else { var destParam = Parameter(newExpr.Type, "d"); blockParams.Add(destParam); blockExprs.Add(Assign(destParam, newExpr)); dest = destParam; } var cast = typeof(Enumerable).GetTypeInfo().DeclaredMethods.First(_ => _.Name == "Cast").MakeGenericMethod(itemParam.Type); var addMethod = typeof(ICollection <>).MakeGenericType(TypeHelper.GetElementType(destExpression.Type)).GetMethod("Add"); if (!sourceExpression.Type.GetTypeInfo().IsGenericType) { sourceExpression = Call(null, cast, sourceExpression); } blockExprs.Add(ForEach(sourceExpression, itemParam, Call( dest, addMethod, itemExpr))); blockExprs.Add(dest); var mapExpr = Block(blockParams, blockExprs); var ifNullExpr = configurationProvider.AllowNullCollections ? Constant(null, destExpression.Type) : newExpr; return(Condition( Equal(sourceExpression, Constant(null)), ToType(ifNullExpr, destExpression.Type), ToType(mapExpr, destExpression.Type))); }
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)); }
private static Expression TryPropertyMap( PropertyMap pm, IConfigurationProvider configurationProvider, TypeMapRegistry registry, ParameterExpression srcParam, ParameterExpression destParam, ParameterExpression ctxtParam) { var pmExpression = CreatePropertyMapFunc(pm, configurationProvider, registry, srcParam, destParam, ctxtParam); if (pmExpression == null) return null; var exception = Parameter(typeof (Exception), "ex"); var mappingExceptionCtor = ((NewExpression)CtorExpression.Body).Constructor; return TryCatch(Block(typeof (void), pmExpression), MakeCatchBlock(typeof (Exception), exception, Throw(New(mappingExceptionCtor, Constant("Error mapping types."), exception, Constant(pm.TypeMap.Types), Constant(pm.TypeMap), Constant(pm))), null)); }
private static Expression BuildValueResolverFunc(PropertyMap propertyMap, TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, Expression destValueExpr, ParameterExpression ctxtParam) { Expression valueResolverFunc; var valueResolverConfig = propertyMap.ValueResolverConfig; var typeMap = propertyMap.TypeMap; if (valueResolverConfig != null) { Expression ctor; Type resolverType; if (valueResolverConfig.Instance != null) { ctor = Constant(valueResolverConfig.Instance); resolverType = valueResolverConfig.Instance.GetType(); } else { ctor = Call(MakeMemberAccess(ctxtParam, typeof(ResolutionContext).GetProperty("Options")), typeof(MappingOperationOptions).GetMethod("CreateInstance") .MakeGenericMethod(valueResolverConfig.Type) ); resolverType = valueResolverConfig.Type; } Expression sourceFunc; if (valueResolverConfig.SourceMember != null) { sourceFunc = valueResolverConfig.SourceMember.ReplaceParameters(srcParam); } else if (valueResolverConfig.SourceMemberName != null) { sourceFunc = MakeMemberAccess(srcParam, typeMap.SourceType.GetFieldOrProperty(valueResolverConfig.SourceMemberName)); } else { sourceFunc = srcParam; } var iResolverType = resolverType.GetTypeInfo() .ImplementedInterfaces.First(t => t.ImplementsGenericInterface(typeof(IValueResolver <,>))); var sourceResolverParam = iResolverType.GetGenericArguments()[0]; var destResolverParam = iResolverType.GetGenericArguments()[1]; valueResolverFunc = ToType(Call(ToType(ctor, resolverType), resolverType.GetMethod("Resolve"), ToType(sourceFunc, sourceResolverParam), ToType(destValueExpr, destResolverParam), ctxtParam), propertyMap.DestinationPropertyType); } else if (propertyMap.CustomResolver != null) { valueResolverFunc = propertyMap.CustomResolver.ReplaceParameters(srcParam, destValueExpr, ctxtParam); } else if (propertyMap.CustomExpression != null) { valueResolverFunc = propertyMap.CustomExpression.ReplaceParameters(srcParam).IfNotNull(); } else if (propertyMap.SourceMembers.Any() && propertyMap.SourceType != null ) { var last = propertyMap.SourceMembers.Last(); var pi = last.MemberInfo as PropertyInfo; if (pi != null && pi.GetGetMethod(true) == null) { valueResolverFunc = Default(last.MemberType); } else { valueResolverFunc = propertyMap.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) ); valueResolverFunc = valueResolverFunc.IfNotNull(); } } else if (propertyMap.SourceMember != null) { valueResolverFunc = MakeMemberAccess(srcParam, propertyMap.SourceMember); } else { valueResolverFunc = Throw(Constant(new Exception("I done blowed up"))); } if (propertyMap.DestinationPropertyType == typeof(string) && valueResolverFunc.Type != typeof(string) && typeMapRegistry.GetTypeMap(new TypePair(valueResolverFunc.Type, propertyMap.DestinationPropertyType)) == null) { valueResolverFunc = Call(valueResolverFunc, valueResolverFunc.Type.GetMethod("ToString", new Type[0])); } if (propertyMap.NullSubstitute != null) { Expression value = Constant(propertyMap.NullSubstitute); if (propertyMap.NullSubstitute.GetType() != propertyMap.DestinationPropertyType) { value = ToType(value, propertyMap.DestinationPropertyType); } valueResolverFunc = MakeBinary(ExpressionType.Coalesce, valueResolverFunc, value); } else if (!typeMap.Profile.AllowNullDestinationValues) { var toCreate = propertyMap.SourceType ?? propertyMap.DestinationPropertyType; if (!toCreate.GetTypeInfo().IsValueType) { valueResolverFunc = MakeBinary(ExpressionType.Coalesce, valueResolverFunc, ToType(Call( typeof(ObjectCreator).GetMethod("CreateNonNullValue"), Constant(toCreate) ), propertyMap.SourceType)); } } return(valueResolverFunc); }
private static Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression itemParam, Expression contextParam, TypePair typePair) { Expression itemExpr; var typeMap = configurationProvider.ResolveTypeMap(typePair); if (typeMap != null && (typeMap.TypeConverterType != null || typeMap.CustomMapper != null)) { if (!typeMap.Sealed) typeMap.Seal(typeMapRegistry, configurationProvider); return typeMap.MapExpression.ReplaceParameters(itemParam, Default(typePair.DestinationType), contextParam); } var match = configurationProvider.GetMappers().FirstOrDefault(m => m.IsMatch(typePair)); if (match != null && typeMap == null) { itemExpr = ToType( match.MapExpression(typeMapRegistry, configurationProvider, propertyMap, itemParam, Default(typePair.DestinationType), contextParam), typePair.DestinationType); } else { var mapMethod = typeof (ResolutionContext).GetDeclaredMethods() .First(m => m.Name == "Map") .MakeGenericMethod(typePair.SourceType, typePair.DestinationType); itemExpr = Call(contextParam, mapMethod, itemParam, Default(typePair.DestinationType)); } return itemExpr; }
private static Expression CreatePropertyMapFunc( PropertyMap propertyMap, IConfigurationProvider configurationProvider, TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, ParameterExpression destParam, ParameterExpression ctxtParam) { var destMember = MakeMemberAccess(destParam, propertyMap.DestinationProperty); Expression getter; var pi = propertyMap.DestinationProperty as PropertyInfo; if (pi != null && pi.GetGetMethod(true) == null) { getter = Default(propertyMap.DestinationPropertyType); } else { getter = destMember; } var destValueExpr = propertyMap.UseDestinationValue ? getter : Default(propertyMap.DestinationPropertyType); var valueResolverExpr = BuildValueResolverFunc(propertyMap, typeMapRegistry, srcParam, destParam, getter, ctxtParam); if (propertyMap.DestinationPropertyType != null) { var typePair = new TypePair(valueResolverExpr.Type, propertyMap.DestinationPropertyType); var typeMap = configurationProvider.ResolveTypeMap(typePair); var match = configurationProvider.GetMappers().FirstOrDefault(m => m.IsMatch(typePair)); if (typeMap != null && (typeMap.TypeConverterType != null || typeMap.CustomMapper != null)) { if(typeMap.Sealed != true) typeMap.Seal(typeMapRegistry, configurationProvider); valueResolverExpr = typeMap.MapExpression.ConvertReplaceParameters(valueResolverExpr, destValueExpr, ctxtParam); } else if (match != null && typeMap == null) { valueResolverExpr = match.MapExpression(typeMapRegistry, configurationProvider, propertyMap, valueResolverExpr, destValueExpr, ctxtParam); } else { valueResolverExpr = SetMap(propertyMap, valueResolverExpr, destValueExpr, ctxtParam); } } else { valueResolverExpr = SetMap(propertyMap, valueResolverExpr, destValueExpr, ctxtParam); } Expression mapperExpr; if (propertyMap.DestinationProperty is FieldInfo) { mapperExpr = propertyMap.SourceType != propertyMap.DestinationPropertyType ? Assign(destMember, ToType(valueResolverExpr, propertyMap.DestinationPropertyType)) : Assign(getter, valueResolverExpr); } else { var setter = ((PropertyInfo) propertyMap.DestinationProperty).GetSetMethod(true); if (setter == null) { mapperExpr = valueResolverExpr; } else { mapperExpr = Assign(destMember, propertyMap.SourceType != propertyMap.DestinationPropertyType ? ToType(valueResolverExpr, propertyMap.DestinationPropertyType) : valueResolverExpr); } } if (propertyMap.PreCondition != null) { mapperExpr = IfThen( propertyMap.PreCondition.ConvertReplaceParameters(srcParam, ctxtParam), mapperExpr ); } if (propertyMap.Condition != null) { mapperExpr = IfThen( propertyMap.Condition.ConvertReplaceParameters( srcParam, destParam, ToType(valueResolverExpr, propertyMap.Condition.Parameters[2].Type), ToType(getter, propertyMap.Condition.Parameters[2].Type), ctxtParam ), mapperExpr ); } return mapperExpr; }
private static Expression CreateAssignmentFunc( TypeMap typeMap, IConfigurationProvider configurationProvider, TypeMapRegistry registry, ParameterExpression srcParam, ParameterExpression destParam, ParameterExpression ctxtParam, Expression destinationFunc, ref ParameterExpression contextToReuse) { var assignTypeMap = Assign(MakeMemberAccess(ctxtParam, typeof (ResolutionContext).GetProperty("TypeMap")), Constant(typeMap)); var beforeMap = Call(ctxtParam, typeof (ResolutionContext).GetMethod("BeforeMap"), ToObject(destParam)); ParameterExpression propertyContext = contextToReuse; var typeMaps = typeMap.GetPropertyMaps() .Where(pm => pm.CanResolveValue()) .Select(pm => TryPropertyMap(pm, configurationProvider, registry, srcParam, destParam, ctxtParam, ref propertyContext)) .ToList(); contextToReuse = propertyContext; var afterMap = Call(ctxtParam, typeof (ResolutionContext).GetMethod("AfterMap"), ToObject(destParam)); var actions = typeMaps; foreach (var beforeMapAction in typeMap.BeforeMapActions) { actions.Insert(0, beforeMapAction.ReplaceParameters(srcParam, destParam, ctxtParam)); } actions.Insert(0, beforeMap); actions.Insert(0, destinationFunc); actions.Insert(0, assignTypeMap); ParameterExpression[] variables; if(propertyContext != null) { var createPropertyContext = CreatePropertyContext(propertyContext, ctxtParam); actions.Insert(0, createPropertyContext); variables = new[] { propertyContext }; } else { variables = new ParameterExpression[0]; } actions.Add(afterMap); actions.AddRange( typeMap.AfterMapActions.Select( afterMapAction => afterMapAction.ReplaceParameters(srcParam, destParam, ctxtParam))); actions.Add(destParam); return Block(variables, actions); }
private static Expression CreateNewDestinationFunc( TypeMap typeMap, TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, ParameterExpression ctxtParam, ref ParameterExpression contextToReuse) { if (typeMap.DestinationCtor != null) return typeMap.DestinationCtor.ReplaceParameters(srcParam, ctxtParam); if (typeMap.ConstructDestinationUsingServiceLocator) return Call(MakeMemberAccess(ctxtParam, typeof (ResolutionContext).GetProperty("Options")), typeof (MappingOperationOptions).GetMethod("CreateInstance") .MakeGenericMethod(typeMap.DestinationType) ); if (typeMap.ConstructorMap?.CanResolve == true) return typeMap.ConstructorMap.BuildExpression(typeMapRegistry, srcParam, ctxtParam, ref contextToReuse); if (typeMap.DestinationType.IsInterface()) { #if PORTABLE Block(typeof (object), Throw( Constant( new PlatformNotSupportedException("Mapping to interfaces through proxies not supported."))), Constant(null)); #else var ctor = Call(Constant(ObjectCreator.DelegateFactory), typeof(DelegateFactory).GetMethod("CreateCtor", new[] { typeof(Type) }), Call(New(typeof(ProxyGenerator)), typeof(ProxyGenerator).GetMethod("GetProxyType"), Constant(typeMap.DestinationType))); return Invoke(ctor); #endif } if (typeMap.DestinationType.IsAbstract()) return Constant(null); if (typeMap.DestinationType.IsGenericTypeDefinition()) return Constant(null); return DelegateFactory.GenerateConstructorExpression(typeMap.DestinationType); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { return(Expression.Call(null, MapMethodInfo, sourceExpression)); }
private static Expression CreatePropertyMapFunc( PropertyMap propertyMap, IConfigurationProvider configurationProvider, TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, ParameterExpression destParam, ParameterExpression ctxtParam, ref ParameterExpression propertyContext) { var valueResolverExpr = BuildValueResolverFunc(propertyMap, typeMapRegistry, srcParam, ctxtParam); var destMember = MakeMemberAccess(destParam, propertyMap.DestinationProperty.MemberInfo); Expression getter; var pi = propertyMap.DestinationProperty.MemberInfo as PropertyInfo; if (pi != null && pi.GetGetMethod(true) == null) { getter = Default(propertyMap.DestinationPropertyType); } else { getter = destMember; } var destValueExpr = propertyMap.UseDestinationValue ? getter : Default(propertyMap.TypeMap.DestinationType); if (propertyMap.SourceType != null && propertyMap.DestinationPropertyType != null) { var typePair = new TypePair(propertyMap.SourceType, propertyMap.DestinationPropertyType); var typeMap = typeMapRegistry.GetTypeMap(typePair); if (typeMap != null && (typeMap.TypeConverterType != null || typeMap.CustomMapper != null)) { if(!typeMap.Sealed) typeMap.Seal(typeMapRegistry, configurationProvider); valueResolverExpr = typeMap.MapExpression.ReplaceParameters(valueResolverExpr, destValueExpr, ctxtParam); } else { var match = configurationProvider.GetMappers().FirstOrDefault(m => m.IsMatch(typePair)); var expressionMapper = match as IObjectMapExpression; if (expressionMapper != null) valueResolverExpr = expressionMapper.MapExpression(valueResolverExpr, destValueExpr, ctxtParam); else valueResolverExpr = SetMap(propertyMap, valueResolverExpr, destValueExpr, ref propertyContext); } } else { valueResolverExpr = SetMap(propertyMap, valueResolverExpr, destValueExpr, ref propertyContext); } if (propertyMap.Condition != null) { valueResolverExpr = Condition( Invoke( propertyMap.Condition, srcParam, destParam, ToType(valueResolverExpr, propertyMap.Condition.Parameters[2].Type), ToType(destValueExpr, propertyMap.Condition.Parameters[2].Type), ctxtParam ), Convert(valueResolverExpr, propertyMap.DestinationPropertyType), destValueExpr ); } Expression mapperExpr; if (propertyMap.DestinationProperty.MemberInfo is FieldInfo) { mapperExpr = propertyMap.SourceType != propertyMap.DestinationPropertyType ? Assign(destMember, Convert(valueResolverExpr, propertyMap.DestinationPropertyType)) : Assign(getter, valueResolverExpr); } else { var setter = ((PropertyInfo) propertyMap.DestinationProperty.MemberInfo).GetSetMethod(true); if (setter == null) { mapperExpr = valueResolverExpr; } else { mapperExpr = Assign(destMember, propertyMap.SourceType != propertyMap.DestinationPropertyType ? Convert(valueResolverExpr, propertyMap.DestinationPropertyType) : valueResolverExpr); } } if (propertyMap.PreCondition != null) { mapperExpr = IfThen( Invoke(propertyMap.PreCondition, srcParam, ctxtParam), mapperExpr ); } return mapperExpr; }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { return(Expression.Call(null, MapMethodInfo.MakeGenericMethod(sourceExpression.Type, destExpression.Type), sourceExpression, destExpression, contextExpression, Expression.Constant(CollectionMapperExtensions.Constructor(destExpression.Type)))); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { var typeMap = new TypePair(sourceExpression.Type, destExpression.Type); return(_converters[typeMap].Value.ReplaceParameters(sourceExpression)); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { var typeMap = new TypePair(sourceExpression.Type, destExpression.Type); return _converters[typeMap].ReplaceParameters(sourceExpression); }
public static LambdaExpression BuildMapperFunc(TypeMap typeMap, IConfigurationProvider configurationProvider, TypeMapRegistry typeMapRegistry) { if (typeMap.SourceType.IsGenericTypeDefinition() || typeMap.DestinationTypeToUse.IsGenericTypeDefinition()) { return(null); } var srcParam = Parameter(typeMap.SourceType, "src"); var destParam = Parameter(typeMap.DestinationTypeToUse, "dest"); var ctxtParam = Parameter(typeof(ResolutionContext), "ctxt"); if (typeMap.Substitution != null) { return(Lambda(typeMap.Substitution.ReplaceParameters(srcParam, destParam, ctxtParam), srcParam, destParam, ctxtParam)); } if (typeMap.TypeConverterType != null) { Type type; if (typeMap.TypeConverterType.IsGenericTypeDefinition()) { var genericTypeParam = typeMap.SourceType.IsGenericType() ? typeMap.SourceType.GetTypeInfo().GenericTypeArguments[0] : typeMap.DestinationTypeToUse.GetTypeInfo().GenericTypeArguments[0]; type = typeMap.TypeConverterType.MakeGenericType(genericTypeParam); } else { type = typeMap.TypeConverterType; } // (src, dest, ctxt) => ((ITypeConverter<TSource, TDest>)ctxt.Options.CreateInstance<TypeConverterType>()).ToType(src, ctxt); var converterInterfaceType = typeof(ITypeConverter <,>).MakeGenericType(typeMap.SourceType, typeMap.DestinationTypeToUse); return(Lambda( Call( ToType( Call( MakeMemberAccess(ctxtParam, typeof(ResolutionContext).GetProperty("Options")), typeof(MappingOperationOptions).GetMethod("CreateInstance") .MakeGenericMethod(type) ), converterInterfaceType), converterInterfaceType.GetMethod("Convert"), srcParam, ctxtParam ), srcParam, destParam, ctxtParam)); } if (typeMap.CustomMapper != null) { return(Lambda(typeMap.CustomMapper.ReplaceParameters(srcParam, destParam, ctxtParam), srcParam, destParam, ctxtParam)); } if (typeMap.CustomProjection != null) { return(Lambda(typeMap.CustomProjection.ReplaceParameters(srcParam), srcParam, destParam, ctxtParam)); } var destinationFunc = CreateDestinationFunc(typeMap, typeMapRegistry, srcParam, destParam, ctxtParam); var assignmentFunc = CreateAssignmentFunc(typeMap, configurationProvider, typeMapRegistry, srcParam, destParam, ctxtParam, destinationFunc); var mapperFunc = CreateMapperFunc(typeMap, srcParam, destParam, ctxtParam, assignmentFunc); var lambdaExpr = Lambda(mapperFunc, srcParam, destParam, ctxtParam); return(lambdaExpr); }
public static Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, TypePair typePair, Expression sourceParameter, Expression contextParameter, PropertyMap propertyMap = null, Expression destinationParameter = null) { if(destinationParameter == null) { destinationParameter = Default(typePair.DestinationType); } var typeMap = configurationProvider.ResolveTypeMap(typePair); if(typeMap != null) { if(!typeMap.HasDerivedTypesToInclude()) { typeMap.Seal(typeMapRegistry, configurationProvider); if(typeMap.MapExpression != null) { return typeMap.MapExpression.ConvertReplaceParameters(sourceParameter, destinationParameter, contextParameter); } else { return ContextMap(typePair, sourceParameter, contextParameter, destinationParameter); } } else { return ContextMap(typePair, sourceParameter, contextParameter, destinationParameter); } } var match = configurationProvider.GetMappers().FirstOrDefault(m => m.IsMatch(typePair)); if(match != null) { var mapperExpression = match.MapExpression(typeMapRegistry, configurationProvider, propertyMap, sourceParameter, destinationParameter, contextParameter); return ToType(mapperExpression, typePair.DestinationType); } return ContextMap(typePair, sourceParameter, contextParameter, destinationParameter); }
private static Expression CreateAssignmentFunc( TypeMap typeMap, IConfigurationProvider configurationProvider, TypeMapRegistry registry, ParameterExpression srcParam, ParameterExpression destParam, ParameterExpression ctxtParam, Expression destinationFunc) { var typeMaps = typeMap.GetPropertyMaps() .Where(pm => pm.CanResolveValue() && !typeMap.IsMappedThroughConstructor(pm.DestinationProperty.Name)) .Select(pm => TryPropertyMap(pm, configurationProvider, registry, srcParam, destParam, ctxtParam)) .ToList(); var actions = typeMaps; foreach (var beforeMapAction in typeMap.BeforeMapActions) { actions.Insert(0, beforeMapAction.ReplaceParameters(srcParam, destParam, ctxtParam)); } actions.Insert(0, destinationFunc); if (typeMap.MaxDepth > 0) { actions.Insert(0, Call(ctxtParam, ((MethodCallExpression)IncTypeDepthInfo.Body).Method, Constant(typeMap.Types))); } actions.AddRange( typeMap.AfterMapActions.Select( afterMapAction => afterMapAction.ReplaceParameters(srcParam, destParam, ctxtParam))); if (typeMap.MaxDepth > 0) { actions.Add(Call(ctxtParam, ((MethodCallExpression)DecTypeDepthInfo.Body).Method, Constant(typeMap.Types))); } actions.Add(destParam); return Block(actions); }
public static LambdaExpression BuildMapperFunc(TypeMap typeMap, IConfigurationProvider configurationProvider, TypeMapRegistry typeMapRegistry) { if (typeMap.SourceType.IsGenericTypeDefinition() || typeMap.DestinationType.IsGenericTypeDefinition()) return null; var srcParam = Parameter(typeMap.SourceType, "src"); var destParam = Parameter(typeMap.DestinationType, "dest"); var ctxtParam = Parameter(typeof (ResolutionContext), "ctxt"); if (typeMap.Substitution != null) { return Lambda(typeMap.Substitution.ReplaceParameters(srcParam, destParam, ctxtParam), srcParam, destParam, ctxtParam); } if (typeMap.TypeConverterType != null) { Type type; if (typeMap.TypeConverterType.IsGenericTypeDefinition()) { var genericTypeParam = typeMap.SourceType.IsGenericType() ? typeMap.SourceType.GetTypeInfo().GenericTypeArguments[0] : typeMap.DestinationType.GetTypeInfo().GenericTypeArguments[0]; type = typeMap.TypeConverterType.MakeGenericType(genericTypeParam); } else type = typeMap.TypeConverterType; // (src, dest, ctxt) => ((ITypeConverter<TSource, TDest>)ctxt.Options.CreateInstance<TypeConverterType>()).Convert(src, ctxt); var converterInterfaceType = typeof (ITypeConverter<,>).MakeGenericType(typeMap.SourceType, typeMap.DestinationType); return Lambda( Call( Convert( Call( MakeMemberAccess(ctxtParam, typeof (ResolutionContext).GetProperty("Options")), typeof (MappingOperationOptions).GetMethod("CreateInstance") .MakeGenericMethod(type) ), converterInterfaceType), converterInterfaceType.GetMethod("Convert"), srcParam, ctxtParam ), srcParam, destParam, ctxtParam); } if (typeMap.CustomMapper != null) { return Lambda(typeMap.CustomMapper.ReplaceParameters(srcParam, destParam, ctxtParam), srcParam, destParam, ctxtParam); } if (typeMap.CustomProjection != null) { return Lambda(typeMap.CustomProjection.ReplaceParameters(srcParam), srcParam, destParam, ctxtParam); } ParameterExpression contextToReuse = null; var destinationFunc = CreateDestinationFunc(typeMap, typeMapRegistry, srcParam, destParam, ctxtParam, ref contextToReuse); var assignmentFunc = CreateAssignmentFunc(typeMap, configurationProvider, typeMapRegistry, srcParam, destParam, ctxtParam, destinationFunc, ref contextToReuse); var mapperFunc = CreateMapperFunc(typeMap, srcParam, destParam, ctxtParam, assignmentFunc); var lambdaExpr = Lambda(mapperFunc, srcParam, destParam, ctxtParam); return lambdaExpr; }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { var sourceElementType = TypeHelper.GetElementType(sourceExpression.Type); var destElementType = TypeHelper.GetElementType(destExpression.Type); if (destExpression.Type.IsAssignableFrom(sourceExpression.Type) && configurationProvider.ResolveTypeMap(sourceElementType, destElementType) == null) { // return (TDestination[]) source; var convertExpr = Convert(sourceExpression, destElementType.MakeArrayType()); if (configurationProvider.Configuration.AllowNullCollections) { return(convertExpr); } // return (TDestination[]) source ?? new TDestination[0]; return(Coalesce(convertExpr, NewArrayBounds(destElementType, Constant(0)))); } var ifNullExpr = configurationProvider.Configuration.AllowNullCollections ? (Expression)Constant(null, destExpression.Type) : NewArrayBounds(destElementType, Constant(0)); var itemParam = Parameter(sourceElementType, "item"); var itemExpr = typeMapRegistry.MapItemExpr(configurationProvider, propertyMap, sourceExpression.Type, destExpression.Type, itemParam, contextExpression); //var count = source.Count(); //var array = new TDestination[count]; //int i = 0; //foreach (var item in source) // array[i++] = newItemFunc(item, context); //return array; var countParam = Parameter(typeof(int), "count"); var arrayParam = Parameter(destExpression.Type, "destinationArray"); var indexParam = Parameter(typeof(int), "destinationArrayIndex"); var actions = new List <Expression>(); var parameters = new List <ParameterExpression> { countParam, arrayParam, indexParam }; var countMethod = typeof(Enumerable) .GetTypeInfo() .DeclaredMethods .Single(mi => mi.Name == "Count" && mi.GetParameters().Length == 1) .MakeGenericMethod(sourceElementType); actions.Add(Assign(countParam, Call(countMethod, sourceExpression))); actions.Add(Assign(arrayParam, NewArrayBounds(destElementType, countParam))); actions.Add(Assign(indexParam, Constant(0))); actions.Add(ForEach(sourceExpression, itemParam, Assign(ArrayAccess(arrayParam, PostIncrementAssign(indexParam)), itemExpr) )); actions.Add(arrayParam); var mapExpr = Block(parameters, actions); // return (source == null) ? ifNullExpr : Map<TSourceElement, TDestElement>(source, context); return(Condition(Equal(sourceExpression, Constant(null)), ifNullExpr, mapExpr)); }
private static Expression TryPropertyMap( PropertyMap pm, IConfigurationProvider configurationProvider, TypeMapRegistry registry, ParameterExpression srcParam, ParameterExpression destParam, ParameterExpression ctxtParam, ref ParameterExpression propertyContext) { var pmExpression = CreatePropertyMapFunc(pm, configurationProvider, registry, srcParam, destParam, ctxtParam, ref propertyContext); if (pmExpression == null) return null; var autoMapException = Parameter(typeof (AutoMapperMappingException), "ex"); var exception = Parameter(typeof (Exception), "ex"); var mappingExceptionCtor = typeof (AutoMapperMappingException).GetTypeInfo() .DeclaredConstructors.First(ci => ci.GetParameters().Length == 3); return TryCatch(Block(typeof (void), pmExpression), MakeCatchBlock(typeof (AutoMapperMappingException), autoMapException, Block(Assign(Property(autoMapException, "PropertyMap"), Constant(pm)), Rethrow()), null), MakeCatchBlock(typeof (Exception), exception, Throw(New(mappingExceptionCtor, ctxtParam, exception, Constant(pm))), null)); }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, Expression sourceExpression, Expression destExpression, Expression contextExpression) { return(sourceExpression); }
private static Expression BuildValueResolverFunc(PropertyMap propertyMap, TypeMapRegistry typeMapRegistry, ParameterExpression srcParam, ParameterExpression ctxtParam) { Expression valueResolverFunc; var valueResolverConfig = propertyMap.ValueResolverConfig; var typeMap = propertyMap.TypeMap; if (valueResolverConfig != null) { Expression ctor; Type resolverType; if (valueResolverConfig.Instance != null) { ctor = Constant(valueResolverConfig.Instance); resolverType = valueResolverConfig.Instance.GetType(); } else { ctor = Call(MakeMemberAccess(ctxtParam, typeof (ResolutionContext).GetProperty("Options")), typeof (MappingOperationOptions).GetMethod("CreateInstance") .MakeGenericMethod(valueResolverConfig.Type) ); resolverType = valueResolverConfig.Type; } Expression sourceFunc; if (valueResolverConfig.SourceMember != null) { sourceFunc = valueResolverConfig.SourceMember.ReplaceParameters(srcParam); } else if (valueResolverConfig.SourceMemberName != null) { sourceFunc = MakeMemberAccess(srcParam, typeMap.SourceType.GetFieldOrProperty(valueResolverConfig.SourceMemberName)); } else { sourceFunc = srcParam; } valueResolverFunc = Convert(Call(ToType(ctor, resolverType), resolverType.GetMethod("Resolve"), sourceFunc, ctxtParam), propertyMap.DestinationPropertyType); } else if (propertyMap.CustomValue != null) { valueResolverFunc = Constant(propertyMap.CustomValue); } else if (propertyMap.CustomResolver != null) { valueResolverFunc = propertyMap.CustomResolver.ReplaceParameters(srcParam, ctxtParam); } else if (propertyMap.CustomExpression != null) { valueResolverFunc = propertyMap.CustomExpression.ReplaceParameters(srcParam).IfNotNull(); } else if (propertyMap.SourceMembers.Any() && propertyMap.SourceType != null ) { var last = propertyMap.SourceMembers.Last(); var pi = last.MemberInfo as PropertyInfo; if (pi != null && pi.GetGetMethod(true) == null) { valueResolverFunc = Default(last.MemberType); } else { valueResolverFunc = propertyMap.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) ); valueResolverFunc = valueResolverFunc.IfNotNull(); } } else if (propertyMap.SourceMember != null) { valueResolverFunc = MakeMemberAccess(srcParam, propertyMap.SourceMember); } else { valueResolverFunc = Throw(Constant(new Exception("I done blowed up"))); } if (propertyMap.DestinationPropertyType == typeof (string) && valueResolverFunc.Type != typeof (string) && typeMapRegistry.GetTypeMap(new TypePair(valueResolverFunc.Type, propertyMap.DestinationPropertyType)) == null) { valueResolverFunc = Call(valueResolverFunc, valueResolverFunc.Type.GetMethod("ToString", new Type[0])); } if (propertyMap.NullSubstitute != null) { Expression value = Constant(propertyMap.NullSubstitute); if (propertyMap.NullSubstitute.GetType() != propertyMap.DestinationPropertyType) value = Convert(value, propertyMap.DestinationPropertyType); valueResolverFunc = MakeBinary(ExpressionType.Coalesce, valueResolverFunc, value); } else if (!typeMap.Profile.AllowNullDestinationValues) { var toCreate = propertyMap.SourceType ?? propertyMap.DestinationPropertyType; if (!toCreate.GetTypeInfo().IsValueType) { valueResolverFunc = MakeBinary(ExpressionType.Coalesce, valueResolverFunc, Convert(Call( typeof (ObjectCreator).GetMethod("CreateNonNullValue"), Constant(toCreate) ), propertyMap.SourceType)); } } return valueResolverFunc; }
public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) { return sourceExpression; }