コード例 #1
0
 public void Apply(MappingStrategy strategy, MappingStrategyBuildContext context)
 {
     foreach (var pattern in mappingPatterns)
     {
         pattern.Contribute(strategy);
     }
 }
コード例 #2
0
 public void Apply(MappingStrategy strategy, MappingStrategyBuildContext context)
 {
     foreach (var mappingStep in strategy.MappingSteps)
     {
         mappingStep.Conversion = context.ApplyConverter(mappingStep, withFallback: true);
     }
 }
コード例 #3
0
 static LambdaExpression GenerateLambda(MappingStrategy strategy, List<Expression> body)
 {
     var lambda = Expression.Lambda(Expression.Block(new[] { strategy.TargetExpression, strategy.SourceExpression }, body),
                                    string.Format("{0} to {1} Converter", strategy.Source.Name, strategy.Target.Name),
                                    new[] { strategy.ContextExpression });
     return lambda;
 }
コード例 #4
0
 public DelegatingConversionVisitor(MappingStrategy strategy, ParameterExpression sourceValueParameter, ParameterExpression mapperParameter, ParameterExpression contextParameter)
 {
     this.strategy = strategy;
     this.sourceValueParameter = sourceValueParameter;
     this.mapperParameter = mapperParameter;
     this.contextParameter = contextParameter;
 }
コード例 #5
0
        static void InitSource(MappingStrategy strategy, List <Expression> body)
        {
            var step = Expression.Assign(strategy.SourceExpression, Expression.Convert(Expression.Property(strategy.ContextExpression, MappingContextMeta.SourceInstance), strategy.Source));

            // we don't describe source. It gets cast from the source to its actual type but that's not interesting and only adds noise to the mapping
            body.Add(step);
        }
コード例 #6
0
ファイル: InitTarget.cs プロジェクト: runerei/Cartographer
        public void Apply(MappingStrategy strategy, MappingStrategyBuildContext context)
        {
            if (strategy.HasTargetInstance)
            {
                strategy.InitTargetStep = new SimpleStep(strategy.Target, strategy.Target, (s, _) => Expression.Convert(Expression.Property(s.ContextExpression, MappingContextMeta.TargetInstance), s.Target));
            }
            else
            {
                if (strategy.TargetConstructor == null)
                {
                    throw new ArgumentException("Constructor not set. This exception message is a work in progress");
                }

                if (strategy.ConstructorParameterMappingSteps == null)
                {
                    throw new ArgumentException("ConstructorParameterMappingSteps not set. This exception message is a work in progress");
                }

                foreach (var mappingStep in strategy.ConstructorParameterMappingSteps.ByKey)
                {
                    if (mappingStep.Value == null)
                    {
                        throw new InvalidOperationException(String.Format("No mapping for constructor parameter {0} has been specified. All constructor parameters need value", mappingStep.Key));
                    }
                    mappingStep.Value.Conversion = context.ApplyConverter(mappingStep.Value, withFallback: true);
                }
                strategy.InitTargetStep = new SimpleStep(strategy.Target, strategy.Target, (s, _) => Expression.New(s.TargetConstructor, GetConstructorParameters(s)));
            }
        }
コード例 #7
0
        static void InitTarget(MappingStrategy strategy, List <Expression> body)
        {
            var step = Expression.Assign(strategy.TargetExpression, TargetInstanceExpression(strategy));

            strategy.Descriptor.DescribeStep(step);
            body.Add(step);
        }
コード例 #8
0
        public void Contribute(MappingStrategy strategy)
        {
            var properties = strategy.Source.GetProperties();
            foreach (var targetProperty in strategy.Target.GetProperties())
            {
                var sourceProperty = Array.Find(properties, p => p.Name == targetProperty.Name);
                if (sourceProperty != null)
                {
                    var assign = new Assign(targetProperty, sourceProperty);

                    strategy.AddMappingStep(assign);
                }
            }
            foreach (var mappingStep in strategy.ConstructorParameterMappingSteps.ByKey)
            {
                if (mappingStep.Value == null)
                {
                    var sourceProperty = Array.Find(properties, p => string.Equals(p.Name, mappingStep.Key.Name, StringComparison.OrdinalIgnoreCase));
                    if (sourceProperty != null)
                    {
                        var assign = new ConstructorAssign(mappingStep.Key, sourceProperty);
                        mappingStep.UpdateValue(assign);
                    }
                }
            }
        }
コード例 #9
0
        static LambdaExpression GenerateLambda(MappingStrategy strategy, List <Expression> body)
        {
            var lambda = Expression.Lambda(Expression.Block(new[] { strategy.TargetExpression, strategy.SourceExpression }, body),
                                           string.Format("{0} to {1} Converter", strategy.Source.Name, strategy.Target.Name),
                                           new[] { strategy.ContextExpression });

            return(lambda);
        }
コード例 #10
0
        public override Expression BuildConversionExpression(MappingStrategy context, MappingStep step)
        {
            var from = step.SourceValueType.GetArrayItemType();
            var to = step.TargetValueType.GetArrayItemType();
            Debug.Assert(from != null);
            Debug.Assert(to != null);

            return Expression.Call(MapCollection.MakeGenericMethod(from, to), context.ValueExpression, context.ContextExpression);
        }
コード例 #11
0
ファイル: AssignChain.cs プロジェクト: runerei/Cartographer
 public override Expression Apply(MappingStrategy strategy, ConversionStep conversion)
 {
     if (nullableProperties == null)
     {
         var value = sourcePropertyChain.Aggregate<PropertyInfo, Expression>(strategy.SourceExpression, Expression.Property);
         return SetValue(strategy, conversion, value);
     }
     return BuildBody(Expression.Property(strategy.SourceExpression, sourcePropertyChain[0]), 0, strategy, conversion);
 }
コード例 #12
0
 public override Expression BuildConversionExpression(MappingStrategy context, MappingStep step)
 {
     var callExpression = (MethodCallExpression)blueprint.Body;
     if (step.TargetValueType == typeof (object))
     {
         return callExpression;
     }
     var method = callExpression.Method.GetGenericMethodDefinition().MakeGenericMethod(step.TargetValueType);
     return Expression.Call(context.MapperExpression, method, context.ValueExpression);
 }
コード例 #13
0
 static void GenerateMapping(MappingStrategy strategy, List <Expression> body)
 {
     foreach (var step in strategy.MappingSteps)
     {
         var map = step.Apply(strategy, step.Conversion);
         strategy.Descriptor.DescribeStep(map);
         body.Add(map);
     }
     body.Add(strategy.TargetExpression);
 }
コード例 #14
0
 public Delegate Compile(MappingStrategy strategy)
 {
     var body = new List<Expression>();
     InitDescriptor(strategy);
     InitSource(strategy, body);
     InitTarget(strategy, body);
     GenerateMapping(strategy, body);
     var lambda = GenerateLambda(strategy, body);
     return lambda.Compile();
 }
コード例 #15
0
 public void Apply(MappingStrategy strategy, MappingStrategyBuildContext context)
 {
     var directMappingStep = new DirectMappingStep(strategy.Source, strategy.Target);
     var converter = context.ApplyConverter(directMappingStep, withFallback: false);
     if (converter != null)
     {
         directMappingStep.Conversion = converter;
         strategy.InitTargetStep = directMappingStep;
         context.MarkAsCompleted();
     }
 }
コード例 #16
0
 public void Contribute(MappingStrategy strategy)
 {
     foreach (var targetProperty in strategy.Target.GetProperties())
     {
         var sourcePropertyChain = BuildPropertyChain(targetProperty, strategy.Source.GetProperties());
         if (sourcePropertyChain.Length > 1)
         {
             strategy.AddMappingStep(new AssignChain(targetProperty, sourcePropertyChain));
         }
     }
 }
コード例 #17
0
ファイル: Assign.cs プロジェクト: runerei/Cartographer
 public override Expression Apply(MappingStrategy strategy, ConversionStep conversion)
 {
     var get = Expression.Property(strategy.SourceExpression, sourceProperty);
     strategy.ValueExpression = get;
     if (conversion != null)
     {
         var convert = conversion.BuildConversionExpression(strategy);
         strategy.ValueExpression = convert;
     }
     var property = Expression.Property(strategy.TargetExpression, targetProperty);
     return Expression.Assign(property, strategy.ValueExpression);
 }
コード例 #18
0
        public void Contribute(MappingStrategy strategy)
        {
            foreach (var targetProperty in strategy.Target.GetProperties())
            {
                var sourceProperty = strategy.Source.GetProperties().FirstOrDefault(p => p.Name == targetProperty.Name);
                if (sourceProperty != null)
                {
                    var assign = new Assign(targetProperty, sourceProperty);

                    strategy.AddMappingStep(assign);
                }
            }
        }
コード例 #19
0
 public MappingStrategy BuildMappingStrategy(Type source, Type target)
 {
     var strategy = new MappingStrategy(source, target, descriptor);
     foreach (var pattern in mappingPatterns)
     {
         pattern.Contribute(strategy);
     }
     foreach (var mappingStep in strategy.MappingSteps)
     {
         ApplyConverter(mappingStep);
     }
     return strategy;
 }
コード例 #20
0
        public Delegate Compile(MappingStrategy strategy)
        {
            var body = new List <Expression>();

            InitDescriptor(strategy);
            InitSource(strategy, body);
            InitTarget(strategy, body);
            GenerateMapping(strategy, body);
            var lambda  = GenerateLambda(strategy, body);
            var reduced = new ReduceExpressionVisitor().Reduce(lambda);

            return(reduced.Compile());
        }
コード例 #21
0
 public void Apply(MappingStrategy strategy, MappingStrategyBuildContext context)
 {
     if (strategy.HasTargetInstance)
     {
         return;
     }
     var ctors = strategy.Target.GetConstructors();
     if (ctors.Length != 1)
     {
         return;
     }
     strategy.TargetConstructor = ctors.Single();
     strategy.ConstructorParameterMappingSteps = new OrderedKeyedCollection<ParameterInfo, MappingStep>(strategy.TargetConstructor.GetParameters());
 }
コード例 #22
0
        public void Contribute(MappingStrategy strategy)
        {
            foreach (var targetProperty in strategy.Target.GetProperties().Where(p => p.Name.EndsWith(targetPropertyNameSuffix, StringComparison.OrdinalIgnoreCase)))
            {
                var expectedName = GetExpectedName(targetProperty);
                var sourceProperty = strategy.Source.GetProperties().FirstOrDefault(p => p.Name == expectedName);
                if (sourceProperty != null)
                {
                    var assign = new Assign(targetProperty, sourceProperty);

                    strategy.AddMappingStep(assign);
                }
            }
        }
コード例 #23
0
 public void Contribute(MappingStrategy strategy)
 {
     if (strategy.ConstructorParameterMappingSteps == null)
     {
         return;
     }
     foreach (var mappingStep in strategy.ConstructorParameterMappingSteps.ByKey)
     {
         if (mappingStep.Value == null)
         {
             var assign = new SimpleStep(mappingStep.Key.ParameterType, mappingStep.Key.ParameterType,
                                         (s, c) => Expression.Call(s.ContextExpression, MappingContextMeta.Argument.MakeGenericMethod(mappingStep.Key.ParameterType)));
             mappingStep.UpdateValue(assign);
         }
     }
 }
コード例 #24
0
ファイル: AssignChain.cs プロジェクト: nulltoken/Cartographer
 public override Expression BuildGetSourceValueExpression(MappingStrategy context)
 {
     if (nullableProperties == null)
     {
         return sourcePropertyChain.Aggregate<PropertyInfo, Expression>(context.SourceExpression, Expression.Property);
     }
     var localTarget = Expression.Variable(TargetValueType, "__value");
     var body = new[]
                {
                	Expression.Assign(localTarget, Expression.Default(TargetValueType)),
                	BuildBody(0, context.SourceExpression, localTarget),
                	localTarget
                };
     var result = Expression.Block(new[] { localTarget }, body);
     return result;
 }
コード例 #25
0
 static void GenerateMapping(MappingStrategy strategy, List<Expression> body)
 {
     foreach (var step in strategy.MappingSteps)
     {
         var get = step.BuildGetSourceValueExpression(strategy);
         strategy.ValueExpression = get;
         if (step.Conversion != null)
         {
             var convert = step.Conversion.BuildConversionExpression(strategy, step);
             strategy.ValueExpression = convert;
         }
         var set = step.BuildSetTargetValueExpression(strategy);
         strategy.Descriptor.DescribeStep(set);
         body.Add(set);
     }
     body.Add(strategy.TargetExpression);
 }
コード例 #26
0
ファイル: AssignChain.cs プロジェクト: runerei/Cartographer
        Expression BuildBody(Expression owner, int index, MappingStrategy strategy, ConversionStep conversion)
        {
            if (index == sourcePropertyChain.Length - 1)
            {
                return SetValue(strategy, conversion, owner);
            }

            if (nullableProperties.Contains(sourcePropertyChain[index]) == false)
            {
                return BuildBody(Expression.Property(owner, sourcePropertyChain[index + 1]), index + 1, strategy, conversion);
            }
            var local = Expression.Variable(owner.Type);
            var property = new PropertyIfNotNullInnerExpression(Expression.Property(local, sourcePropertyChain[index + 1]));
            var body = BuildBody(property, index + 1, strategy, conversion);
            var expression = new PropertyIfNotNullExpression(owner, body, local, TargetValueType);
            property.Owner = expression;
            return expression;
        }
コード例 #27
0
        public MappingStrategy BuildMappingStrategy(MappingInfo mappingInfo)
        {
            var strategy = new MappingStrategy(mappingInfo, descriptor);

            //first try to shortcircuit
            var directMappingStep = new DirectMappingStep(strategy.Source, strategy.Target);
            var converter         = ApplyConverter(directMappingStep, withFallback: false);

            if (converter != null)
            {
                directMappingStep.Conversion = converter;
                strategy.InitTargetStep      = directMappingStep;
                return(strategy);
            }
            foreach (var pattern in mappingPatterns)
            {
                pattern.Contribute(strategy);
            }
            foreach (var mappingStep in strategy.MappingSteps)
            {
                mappingStep.Conversion = ApplyConverter(mappingStep, withFallback: true);
            }
            if (strategy.HasTargetInstance)
            {
                strategy.InitTargetStep = new SimpleStep(strategy.Target, strategy.Target, (s, _) => Expression.Convert(Expression.Property(s.ContextExpression, MappingContextMeta.TargetInstance), s.Target));
            }
            else
            {
                foreach (var mappingStep in strategy.ConstructorParameterMappingSteps.ByKey)
                {
                    if (mappingStep.Value == null)
                    {
                        throw new InvalidOperationException(string.Format("No mapping for constructor parameter {0} has been specified. All constructor parameters need value", mappingStep.Key));
                    }
                    mappingStep.Value.Conversion = ApplyConverter(mappingStep.Value, withFallback: true);
                }
                strategy.InitTargetStep = new SimpleStep(strategy.Target, strategy.Target, (s, _) => Expression.New(s.TargetConstructor, GetConstructorParameters(s)));
            }
            return(strategy);
        }
コード例 #28
0
        public MappingStrategy BuildMappingStrategy(MappingInfo mappingInfo)
        {
            var strategy = new MappingStrategy(mappingInfo, descriptor);

            //first try to shortcircuit
            var directMappingStep = new DirectMappingStep(strategy.Source, strategy.Target);
            var converter = ApplyConverter(directMappingStep, withFallback: false);
            if (converter != null)
            {
                directMappingStep.Conversion = converter;
                strategy.InitTargetStep = directMappingStep;
                return strategy;
            }
            foreach (var pattern in mappingPatterns)
            {
                pattern.Contribute(strategy);
            }
            foreach (var mappingStep in strategy.MappingSteps)
            {
                mappingStep.Conversion = ApplyConverter(mappingStep, withFallback: true);
            }
            if (strategy.HasTargetInstance)
            {
                strategy.InitTargetStep = new SimpleStep(strategy.Target, strategy.Target, (s, _) => Expression.Convert(Expression.Property(s.ContextExpression, MappingContextMeta.TargetInstance), s.Target));
            }
            else
            {
                foreach (var mappingStep in strategy.ConstructorParameterMappingSteps.ByKey)
                {
                    if (mappingStep.Value == null)
                    {
                        throw new InvalidOperationException(string.Format("No mapping for constructor parameter {0} has been specified. All constructor parameters need value", mappingStep.Key));
                    }
                    mappingStep.Value.Conversion = ApplyConverter(mappingStep.Value, withFallback: true);
                }
                strategy.InitTargetStep = new SimpleStep(strategy.Target, strategy.Target, (s, _) => Expression.New(s.TargetConstructor, GetConstructorParameters(s)));
            }
            return strategy;
        }
コード例 #29
0
 public void Contribute(MappingStrategy strategy)
 {
     var sourceProperties = strategy.Source.GetProperties();
     foreach (var targetProperty in strategy.Target.GetProperties())
     {
         var sourcePropertyChain = BuildPropertyChain(targetProperty.Name, sourceProperties);
         if (sourcePropertyChain.Length > 1)
         {
             strategy.AddMappingStep(new AssignChain(targetProperty, sourcePropertyChain));
         }
     }
     foreach (var mappingStep in strategy.ConstructorParameterMappingSteps.ByKey)
     {
         if (mappingStep.Value == null)
         {
             var targetParameter = mappingStep.Key;
             var sourcePropertyChain = BuildPropertyChain(targetParameter.Name, sourceProperties);
             if (sourcePropertyChain.Length > 1)
             {
                 mappingStep.UpdateValue(new ConstructorAssignChain(mappingStep.Key, sourcePropertyChain));
             }
         }
     }
 }
コード例 #30
0
ファイル: AssignChain.cs プロジェクト: nulltoken/Cartographer
 public override Expression BuildSetTargetValueExpression(MappingStrategy context)
 {
     var property = Expression.Property(context.TargetExpression, targetProperty);
     return Expression.Assign(property, context.ValueExpression);
 }
コード例 #31
0
ファイル: MappingStep.cs プロジェクト: runerei/Cartographer
 public abstract Expression Apply(MappingStrategy strategy, ConversionStep conversion);
コード例 #32
0
        static Expression BuildParameterExpression(MappingStep step, MappingStrategy strategy)
        {
            var map = step.Apply(strategy, step.Conversion);

            return(map);
        }
コード例 #33
0
 static Expression[] GetConstructorParameters(MappingStrategy strategy)
 {
     return(strategy.ConstructorParameterMappingSteps.Select(s => BuildParameterExpression(s, strategy)).ToArray());
 }
コード例 #34
0
 static Expression BuildParameterExpression(MappingStep step, MappingStrategy strategy)
 {
     var map = step.Apply(strategy, step.Conversion);
     return map;
 }
コード例 #35
0
 public abstract Expression BuildConversionExpression(MappingStrategy context, MappingStep step);
コード例 #36
0
 static Expression[] GetConstructorParameters(MappingStrategy strategy)
 {
     return strategy.ConstructorParameterMappingSteps.Select(s => BuildParameterExpression(s, strategy)).ToArray();
 }
コード例 #37
0
 void InitDescriptor(MappingStrategy strategy)
 {
     strategy.Descriptor.DescribeMapping(strategy.Source, strategy.Target);
 }
コード例 #38
0
ファイル: SimpleStep.cs プロジェクト: runerei/Cartographer
 public override Expression Apply(MappingStrategy strategy, ConversionStep conversion)
 {
     return apply(strategy, conversion);
 }
コード例 #39
0
 static Expression TargetInstanceExpression(MappingStrategy strategy)
 {
     return(strategy.InitTargetStep.Apply(strategy, strategy.InitTargetStep.Conversion));
 }
コード例 #40
0
ファイル: AssignChain.cs プロジェクト: runerei/Cartographer
 Expression SetValue(MappingStrategy strategy, ConversionStep conversion, Expression value)
 {
     strategy.ValueExpression = value;
     if (conversion != null)
     {
         var convert = conversion.BuildConversionExpression(strategy);
         strategy.ValueExpression = convert;
     }
     return BuildSetTargetValueExpression(strategy);
 }