Ejemplo n.º 1
0
        private Expression CreateMapExpressionCore(ExpressionRequest request, Expression instanceParameter, TypePairCount typePairCount, TypeMap typeMap, LetPropertyMaps letPropertyMaps)
        {
            var bindings = new List <MemberBinding>();
            var depth    = GetDepth(request, typePairCount);

            if (typeMap.MaxDepth > 0 && depth >= typeMap.MaxDepth)
            {
                if (typeMap.Profile.AllowNullDestinationValues)
                {
                    return(null);
                }
            }
            else
            {
                bindings = CreateMemberBindings(request, typeMap, instanceParameter, typePairCount, letPropertyMaps);
            }
            Expression constructorExpression = DestinationConstructorExpression(typeMap, instanceParameter);

            if (instanceParameter is ParameterExpression)
            {
                constructorExpression = ((LambdaExpression)constructorExpression).ReplaceParameters(instanceParameter);
            }
            var visitor = new NewFinderVisitor();

            visitor.Visit(constructorExpression);

            var expression = MemberInit(
                visitor.NewExpression,
                bindings.ToArray()
                );

            return(expression);
        }
Ejemplo n.º 2
0
 private static int GetDepth(ExpressionRequest request, TypePairCount typePairCount)
 {
     if (typePairCount.TryGetValue(request, out int visitCount))
     {
         visitCount = visitCount + 1;
     }
     typePairCount[request] = visitCount;
     return(visitCount);
 }
Ejemplo n.º 3
0
        private List <MemberBinding> CreateMemberBindings(ExpressionRequest request, TypeMap typeMap, Expression instanceParameter, TypePairCount typePairCount, LetPropertyMaps letPropertyMaps)
        {
            var bindings = new List <MemberBinding>();

            foreach (var propertyMap in typeMap.PropertyMaps
                     .Where(pm => (!pm.ExplicitExpansion || request.MembersToExpand.Contains(pm.DestinationMember)) &&
                            pm.CanResolveValue && ReflectionHelper.CanBeSet(pm.DestinationMember))
                     .OrderBy(pm => pm.DestinationName))
            {
                var propertyExpression = new PropertyExpression(propertyMap);
                letPropertyMaps.Push(propertyExpression);

                CreateMemberBinding(propertyExpression);

                letPropertyMaps.Pop();
            }
            return(bindings);

            void CreateMemberBinding(PropertyExpression propertyExpression)
            {
                var propertyMap = propertyExpression.PropertyMap;
                var result      = ResolveExpression(propertyMap, request.SourceType, instanceParameter, letPropertyMaps);

                propertyExpression.Expression = result.ResolutionExpression;
                var propertyTypeMap = _configurationProvider.ResolveTypeMap(result.Type, propertyMap.DestinationType);
                var propertyRequest = new ExpressionRequest(result.Type, propertyMap.DestinationType, request.MembersToExpand, request);

                if (propertyRequest.AlreadyExists)
                {
                    return;
                }
                var binder = _configurationProvider.Binders.FirstOrDefault(b => b.IsMatch(propertyMap, propertyTypeMap, result));

                if (binder == null)
                {
                    var message =
                        $"Unable to create a map expression from {propertyMap.SourceMember?.DeclaringType?.Name}.{propertyMap.SourceMember?.Name} ({result.Type}) to {propertyMap.DestinationMember.DeclaringType?.Name}.{propertyMap.DestinationName} ({propertyMap.DestinationType})";
                    throw new AutoMapperMappingException(message, null, typeMap.Types, typeMap, propertyMap);
                }
                var bindExpression = binder.Build(_configurationProvider, propertyMap, propertyTypeMap, propertyRequest, result, typePairCount, letPropertyMaps);

                if (bindExpression == null)
                {
                    return;
                }
                var rhs = propertyMap.ValueTransformers
                          .Concat(typeMap.ValueTransformers)
                          .Concat(typeMap.Profile.ValueTransformers)
                          .Where(vt => vt.IsMatch(propertyMap))
                          .Aggregate(bindExpression.Expression, (current, vtConfig) => ToType(ReplaceParameters(vtConfig.TransformerExpression, ToType(current, vtConfig.ValueType)), propertyMap.DestinationType));

                bindExpression = bindExpression.Update(rhs);

                bindings.Add(bindExpression);
            }
        }
Ejemplo n.º 4
0
        private Expression CreateMapExpressionCore(ExpressionRequest request, Expression instanceParameter, TypePairCount typePairCount, LetPropertyMaps letPropertyMaps, out TypeMap typeMap)
        {
            typeMap = _configurationProvider.ResolveTypeMap(request.SourceType, request.DestinationType);

            if (typeMap == null)
            {
                throw QueryMapperHelper.MissingMapException(request.SourceType, request.DestinationType);
            }

            if (typeMap.CustomMapExpression != null)
            {
                return(typeMap.CustomMapExpression.ReplaceParameters(instanceParameter));
            }
            return(CreateMapExpressionCore(request, instanceParameter, typePairCount, typeMap, letPropertyMaps));
        }
Ejemplo n.º 5
0
        public LambdaExpression[] CreateMapExpression(ExpressionRequest request, TypePairCount typePairCount, LetPropertyMaps letPropertyMaps)
        {
            // this is the input parameter of this expression with name <variableName>
            var instanceParameter = Parameter(request.SourceType, "dto" + request.SourceType.Name);
            var expressions       = new QueryExpressions(CreateMapExpressionCore(request, instanceParameter, typePairCount, letPropertyMaps, out var typeMap));

            if (letPropertyMaps.Count > 0)
            {
                expressions = letPropertyMaps.GetSubQueryExpression(this, expressions.First, typeMap, request, instanceParameter, typePairCount);
            }
            if (expressions.First == null)
            {
                return(null);
            }
            var firstLambda = Lambda(expressions.First, instanceParameter);

            if (expressions.Second == null)
            {
                return(new[] { firstLambda });
            }
            return(new[] { firstLambda, Lambda(expressions.Second, expressions.SecondParameter) });
        }
Ejemplo n.º 6
0
 private LambdaExpression[] CreateMapExpression(ExpressionRequest request) => CreateMapExpression(request, new Dictionary <ExpressionRequest, int>(),
                                                                                                  new FirstPassLetPropertyMaps(_configurationProvider)
                                                                                                  );
Ejemplo n.º 7
0
 public Expression CreateMapExpression(ExpressionRequest request, Expression instanceParameter, TypePairCount typePairCount, LetPropertyMaps letPropertyMaps)
 {
     return(CreateMapExpressionCore(request, instanceParameter, typePairCount, letPropertyMaps, out var _));
 }
Ejemplo n.º 8
0
        public MemberAssignment Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary <ExpressionRequest, int> typePairCount, LetPropertyMaps letPropertyMaps)
        {
            var defaultDestination = Activator.CreateInstance(propertyMap.DestinationType);

            return(Bind(propertyMap.DestinationMember, Coalesce(result.ResolutionExpression, Constant(defaultDestination))));
        }