Exemple #1
0
        private CompileArgument GetCompileArgument(TypeTuple tuple, MapType mapType, CompileContext context)
        {
            var setting = GetMergedSettings(tuple, mapType);

            return(new CompileArgument
            {
                SourceType = tuple.Source,
                DestinationType = tuple.Destination,
                ExplicitMapping = this.RuleMap.ContainsKey(tuple),
                MapType = mapType,
                Context = context,
                Settings = setting,
            });
        }
Exemple #2
0
        private LambdaExpression CreateProjectionExpression(TypeTuple tuple)
        {
            var context = new CompileContext(this);

            context.Running.Add(tuple);
            try
            {
                return(CreateMapExpression(tuple.Source, tuple.Destination, MapType.Projection, context));
            }
            finally
            {
                context.Running.Remove(tuple);
            }
        }
Exemple #3
0
        internal LambdaExpression CreateMapExpression(TypeTuple tuple, MapType mapType)
        {
            var context = new CompileContext(this);

            context.Running.Add(tuple);
            try
            {
                var arg = GetCompileArgument(tuple, mapType, context);
                return(CreateMapExpression(arg));
            }
            finally
            {
                context.Running.Remove(tuple);
            }
        }
Exemple #4
0
        private Delegate CreateMapToTargetFunction(TypeTuple tuple)
        {
            var context = new CompileContext(this);

            context.Running.Add(tuple);
            try
            {
                var result = CreateMapExpression(tuple.Source, tuple.Destination, MapType.MapToTarget, context);
                return(result.Compile());
            }
            finally
            {
                context.Running.Remove(tuple);
            }
        }
Exemple #5
0
        private Delegate CreateMapFunction(TypeTuple tuple)
        {
            var context = new CompileContext(this);

            context.Running.Add(tuple);
            try
            {
                var result   = CreateMapExpression(tuple.Source, tuple.Destination, MapType.Map, context);
                var compiled = result.Compile();
                if (this == GlobalSettings)
                {
                    var field = typeof(TypeAdapter <,>).MakeGenericType(tuple.Source, tuple.Destination).GetField("Map");
                    field.SetValue(null, compiled);
                }
                return(compiled);
            }
            finally
            {
                context.Running.Remove(tuple);
            }
        }
Exemple #6
0
        private MethodCallExpression CreateProjectionCallExpression(TypeTuple tuple)
        {
            var context = new CompileContext(this);

            context.Running.Add(tuple);
            try
            {
                var lambda     = CreateMapExpression(tuple.Source, tuple.Destination, MapType.Projection, context);
                var source     = Expression.Parameter(typeof(IQueryable <>).MakeGenericType(tuple.Source));
                var methodInfo = (from method in typeof(Queryable).GetMethods()
                                  where method.Name == "Select"
                                  let p = method.GetParameters()[1]
                                          where p.ParameterType.GetGenericArguments()[0].GetGenericTypeDefinition() == typeof(Func <,>)
                                          select method).First().MakeGenericMethod(tuple.Source, tuple.Destination);
                return(Expression.Call(methodInfo, source, Expression.Quote(lambda)));
            }
            finally
            {
                context.Running.Remove(tuple);
            }
        }
Exemple #7
0
        internal LambdaExpression CreateInlineMapExpression(Type sourceType, Type destinationType, MapType mapType, CompileContext context, MemberMapping?mapping = null)
        {
            var tuple       = new TypeTuple(sourceType, destinationType);
            var subFunction = context.IsSubFunction();

            if (!subFunction)
            {
                if (context.Running.Contains(tuple))
                {
                    if (mapType == MapType.Projection)
                    {
                        throw new InvalidOperationException("Projection does not support circular reference");
                    }
                    return(CreateMapInvokeExpression(sourceType, destinationType, mapType));
                }
                context.Running.Add(tuple);
            }

            try
            {
                var arg = GetCompileArgument(tuple, mapType, context);
                if (mapping != null)
                {
                    arg.Settings.Resolvers.AddRange(mapping.NextResolvers);
                    arg.Settings.Ignore.Apply(mapping.NextIgnore);
                    arg.UseDestinationValue = mapping.UseDestinationValue;
                }

                return(CreateMapExpression(arg));
            }
            finally
            {
                if (!subFunction)
                {
                    context.Running.Remove(tuple);
                }
            }
        }
Exemple #8
0
        internal LambdaExpression CreateInlineMapExpression(Type sourceType, Type destinationType, MapType mapType, CompileContext context)
        {
            var tuple = new TypeTuple(sourceType, destinationType);

            if (context.Running.Contains(tuple))
            {
                return(CreateInvokeExpression(sourceType, destinationType));
            }

            context.Running.Add(tuple);
            try
            {
                var exp = CreateMapExpression(sourceType, destinationType, mapType == MapType.Projection ? MapType.Projection : MapType.InlineMap, context);
                if (exp != null)
                {
                    var detector = new BlockExpressionDetector();
                    detector.Visit(exp);
                    if (detector.IsBlockExpression)
                    {
                        exp = null;
                    }
                }
                return(exp ?? CreateInvokeExpression(sourceType, destinationType));
            }
            finally
            {
                context.Running.Remove(tuple);
            }
        }
Exemple #9
0
        private LambdaExpression CreateMapExpression(Type sourceType, Type destinationType, MapType mapType, CompileContext context)
        {
            var setting = GetMergedSettings(sourceType, destinationType, mapType);
            var fn      = mapType == MapType.MapToTarget
                ? setting.ConverterToTargetFactory
                : setting.ConverterFactory;

            if (fn == null)
            {
                if (mapType == MapType.InlineMap)
                {
                    return(null);
                }
                else
                {
                    throw new InvalidOperationException(
                              $"ConverterFactory is not found for the following mapping: TSource: {sourceType} TDestination: {destinationType}");
                }
            }

            var arg = new CompileArgument
            {
                SourceType      = sourceType,
                DestinationType = destinationType,
                MapType         = mapType,
                Context         = context,
                Settings        = setting,
            };

            return(fn(arg));
        }
Exemple #10
0
        internal LambdaExpression CreateInlineMapExpression(Type sourceType, Type destinationType, MapType parentMapType, CompileContext context)
        {
            var tuple = new TypeTuple(sourceType, destinationType);

            if (context.Running.Contains(tuple))
            {
                if (parentMapType == MapType.Projection)
                {
                    throw new InvalidOperationException("Projection does not support circular reference");
                }
                return(CreateMapInvokeExpression(sourceType, destinationType));
            }

            context.Running.Add(tuple);
            try
            {
                var arg = GetCompileArgument(tuple, parentMapType, context);
                var exp = CreateMapExpression(arg, true);
                if (exp != null)
                {
                    var detector = new BlockExpressionDetector();
                    detector.Visit(exp);
                    if (detector.IsBlockExpression)
                    {
                        exp = null;
                    }
                }
                if (exp != null)
                {
                    return(exp);
                }
                if (parentMapType == MapType.MapToTarget)
                {
                    return(CreateMapToTargetInvokeExpression(sourceType, destinationType));
                }
                else
                {
                    return(CreateMapInvokeExpression(sourceType, destinationType));
                }
            }
            finally
            {
                context.Running.Remove(tuple);
            }
        }
Exemple #11
0
        internal LambdaExpression CreateInlineMapExpression(Type sourceType, Type destinationType, MapType mapType, CompileContext context)
        {
            var tuple = new TypeTuple(sourceType, destinationType);

            if (context.Running.Contains(tuple))
            {
                if (mapType == MapType.Projection)
                {
                    throw new InvalidOperationException(
                              $"Projection does not support circular reference: TSource: {sourceType} TDestination: {destinationType}");
                }
                return(CreateInvokeExpression(sourceType, destinationType));
            }

            context.Running.Add(tuple);
            try
            {
                var exp = CreateMapExpression(sourceType, destinationType, mapType == MapType.Projection ? MapType.Projection : MapType.InlineMap, context);
                if (exp != null)
                {
                    var detector = new BlockExpressionDetector();
                    detector.Visit(exp);
                    if (detector.IsBlockExpression)
                    {
                        exp = null;
                    }
                }
                return(exp ?? CreateInvokeExpression(sourceType, destinationType));
            }
            finally
            {
                context.Running.Remove(tuple);
            }
        }
        CompileArgument GetCompileArgument(Type sourceType, Type destinationType, MapType mapType, CompileContext context)
        {
            var setting = GetMergedSettings(sourceType, destinationType, mapType);
            var arg     = new CompileArgument
            {
                SourceType      = sourceType,
                DestinationType = destinationType,
                MapType         = mapType,
                Context         = context,
                Settings        = setting,
            };

            return(arg);
        }