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); }
internal static Expression CreateMapExpression(IMappingEngine mappingEngine, ExpressionRequest request, Expression instanceParameter, Internal.IDictionary <ExpressionRequest, int> typePairCount) { var typeMap = mappingEngine.ConfigurationProvider.FindTypeMapFor(request.SourceType, request.DestinationType); if (typeMap == null) { const string MessageFormat = "Missing map from {0} to {1}. Create using Mapper.CreateMap<{0}, {1}>."; var message = string.Format(MessageFormat, request.SourceType.Name, request.DestinationType.Name); throw new InvalidOperationException(message); } var bindings = CreateMemberBindings(mappingEngine, request, typeMap, instanceParameter, typePairCount); var parameterReplacer = new ParameterReplacementVisitor(instanceParameter); var visitor = new NewFinderVisitor(); var ctorExpr = typeMap.ConstructExpression ?? Expression.Lambda(Expression.New(request.DestinationType)); visitor.Visit(parameterReplacer.Visit(ctorExpr)); var expression = Expression.MemberInit( visitor.NewExpression, bindings.ToArray() ); return(expression); }
public Expression CreateMapExpression(ExpressionRequest request, Expression instanceParameter, ConcurrentDictionary <ExpressionRequest, int> typePairCount) { var typeMap = ConfigurationProvider.ResolveTypeMap(request.SourceType, request.DestinationType); if (typeMap == null) { const string MessageFormat = "Missing map from {0} to {1}. Create using Mapper.CreateMap<{0}, {1}>."; var message = string.Format(MessageFormat, request.SourceType.Name, request.DestinationType.Name); throw new InvalidOperationException(message); } var parameterReplacer = instanceParameter is ParameterExpression ? new ParameterReplacementVisitor(instanceParameter) : null; var customProjection = typeMap.CustomProjection; if (customProjection != null) { return(parameterReplacer == null ? customProjection.Body : parameterReplacer.Visit(customProjection.Body)); } var bindings = new List <MemberBinding>(); var visitCount = typePairCount.AddOrUpdate(request, 0, (tp, i) => i + 1); if (visitCount >= typeMap.MaxDepth) { if (ConfigurationProvider.AllowNullDestinationValues) { return(null); } } else { bindings = CreateMemberBindings(request, typeMap, instanceParameter, typePairCount); } Expression constructorExpression = typeMap.DestinationConstructorExpression(instanceParameter); if (parameterReplacer != null) { constructorExpression = parameterReplacer.Visit(constructorExpression); } var visitor = new NewFinderVisitor(); visitor.Visit(constructorExpression); var expression = Expression.MemberInit( visitor.NewExpression, bindings.ToArray() ); return(expression); }
public Expression CreateMapExpression(ExpressionRequest request, Expression instanceParameter, IDictionary <ExpressionRequest, int> typePairCount) { var typeMap = _configurationProvider.ResolveTypeMap(request.SourceType, request.DestinationType); if (typeMap == null) { throw QueryMapperHelper.MissingMapException(request.SourceType, request.DestinationType); } if (typeMap.CustomProjection != null) { return(typeMap.CustomProjection.ReplaceParameters(instanceParameter)); } 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); } 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); }
public Expression CreateMapExpression(ExpressionRequest request, Expression instanceParameter, Internal.IDictionary<ExpressionRequest, int> typePairCount) { var typeMap = ConfigurationProvider.ResolveTypeMap(request.SourceType, request.DestinationType); if (typeMap == null) { const string MessageFormat = "Missing map from {0} to {1}. Create using Mapper.CreateMap<{0}, {1}>."; var message = string.Format(MessageFormat, request.SourceType.Name, request.DestinationType.Name); throw new InvalidOperationException(message); } var bindings = CreateMemberBindings(request, typeMap, instanceParameter, typePairCount); var parameterReplacer = new ParameterReplacementVisitor(instanceParameter); var visitor = new NewFinderVisitor(); var constructorExpression = typeMap.DestinationConstructorExpression(instanceParameter); visitor.Visit(parameterReplacer.Visit(constructorExpression)); var expression = Expression.MemberInit( visitor.NewExpression, bindings.ToArray() ); return expression; }
private Expression CreateMapExpressionCore(ExpressionRequest request, Expression instanceParameter, TypePairCount typePairCount, TypeMap typeMap, LetPropertyMaps letPropertyMaps) { var memberBindings = new List <MemberBinding>(); var depth = GetDepth(request, typePairCount); if (typeMap.MaxDepth > 0 && depth >= typeMap.MaxDepth) { if (typeMap.Profile.AllowNullDestinationValues) { return(null); } } else { memberBindings = CreateMemberBindings(); } Expression constructorExpression = DestinationConstructorExpression(typeMap, instanceParameter, letPropertyMaps); if (instanceParameter is ParameterExpression) { constructorExpression = ((LambdaExpression)constructorExpression).ReplaceParameters(instanceParameter); } var visitor = new NewFinderVisitor(); visitor.Visit(constructorExpression); var expression = MemberInit( visitor.NewExpression, memberBindings.ToArray() ); return(expression); List <MemberBinding> CreateMemberBindings() { 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 && depth >= _configurationProvider.RecursiveQueriesMaxDepth) { 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); } } }