예제 #1
0
        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));
        }
예제 #2
0
        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));
        }
예제 #3
0
 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)));
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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));
        }
예제 #8
0
 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)
     );
예제 #9
0
        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;
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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;
        }
예제 #14
0
        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);
        }
예제 #15
0
        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;
        }
예제 #16
0
파일: TypeMap.cs 프로젝트: drminor/propbag
        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");
        }
예제 #17
0
        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));
        }
예제 #18
0
        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();
        }