Beispiel #1
0
        private Expression GetDictionaryPopulation(IObjectMappingData mappingData)
        {
            var mapperData = mappingData.MapperData;

            if (mapperData.SourceMember.IsEnumerable)
            {
                return(GetEnumerableToDictionaryMapping(mappingData));
            }

            var memberPopulations = _memberPopulatorFactory
                                    .Create(mappingData)
                                    .Project(memberPopulation => memberPopulation.GetPopulation())
                                    .ToArray();

            if (memberPopulations.None())
            {
                return(null);
            }

            if (memberPopulations.HasOne())
            {
                return(memberPopulations[0]);
            }

            var memberPopulationBlock = Expression.Block(memberPopulations);

            return(memberPopulationBlock);
        }
        public static Expression BuildPopulationLoop <TLoopData>(
            this TLoopData loopData,
            EnumerablePopulationBuilder builder,
            IObjectMappingData mappingData,
            Func <TLoopData, IObjectMappingData, Expression> elementPopulationFactory)
            where TLoopData : IPopulationLoopData
        {
            // TODO: Not all enumerable mappings require the Counter
            var breakLoop = Expression.Break(Expression.Label(typeof(void), "Break"));

            var elementPopulation = elementPopulationFactory.Invoke(loopData, mappingData);

            var loopBody = Expression.Block(
                Expression.IfThen(loopData.LoopExitCheck, breakLoop),
                elementPopulation,
                builder.GetCounterIncrement());

            var populationLoop = loopData.NeedsContinueTarget
                ? Expression.Loop(loopBody, breakLoop.Target, loopData.ContinueLoopTarget)
                : Expression.Loop(loopBody, breakLoop.Target);

            var adaptedLoop = loopData.Adapt(populationLoop);

            var population = Expression.Block(
                new[] { builder.Counter },
                builder.Counter.AssignTo(ToNumericConverter <int> .Zero),
                adaptedLoop);

            return(population);
        }
 public ConstructionKey(IObjectMappingData mappingData)
 {
     MappingData   = mappingData;
     _ruleSet      = mappingData.MappingContext.RuleSet;
     _sourceMember = mappingData.MapperData.SourceMember;
     _targetMember = mappingData.MapperData.TargetMember;
 }
Beispiel #4
0
        public static Expression GetChildMapping(
            IObjectMappingData childMappingData,
            MappingValues mappingValues,
            int dataSourceIndex,
            ObjectMapperData declaredTypeMapperData)
        {
            var childMapperData = childMappingData.MapperData;

            if (childMapperData.IsRepeatMapping &&
                childMapperData.RuleSet.RepeatMappingStrategy.AppliesTo(childMapperData))
            {
                var repeatMappingCall = childMapperData
                                        .RuleSet
                                        .RepeatMappingStrategy
                                        .GetMapRepeatedCallFor(
                    childMappingData,
                    mappingValues,
                    dataSourceIndex,
                    declaredTypeMapperData);

                return(repeatMappingCall);
            }

            var inlineMappingBlock = GetInlineMappingBlock(
                childMappingData,
                mappingValues,
                MappingDataCreationFactory.ForChild(mappingValues, dataSourceIndex, childMapperData));

            return(inlineMappingBlock);
        }
Beispiel #5
0
        private static bool SubMappingNeeded(this IObjectMappingData mappingData, out IObjectMappingData parentMappingData)
        {
            parentMappingData = GetParentMappingData(mappingData);

            return(parentMappingData.MapperDataPopulated &&
                   parentMappingData.MapperData.Context.NeedsRuntimeTypedMapping);
        }
        private ObjectMappingData(
            TSource source,
            TTarget target,
            int?elementIndex,
            object elementKey,
            MappingTypes mappingTypes,
            IMappingContext mappingContext,
            IObjectMappingData declaredTypeMappingData,
            IObjectMappingData parent,
            bool createMapper)
            : base(source, target, elementIndex, elementKey, parent, mappingContext)
        {
            MappingTypes            = mappingTypes;
            MappingContext          = mappingContext;
            DeclaredTypeMappingData = declaredTypeMappingData;

            if (parent != null)
            {
                Parent = parent;
                return;
            }

            if (createMapper)
            {
                _mapper = MapperContext.ObjectMapperFactory.GetOrCreateRoot(this);
            }
        }
 public Expression GetElementMapping(IObjectMappingData enumerableMappingData)
 {
     return(Expression.Condition(
                _sourceEnumerableFound,
                _enumerableLoopData.SourceElement,
                _elementsDictionaryLoopData.GetElementMapping(enumerableMappingData)));
 }
        private void AddDerivedSourceTypePopulations(
            IPopulationLoopData loopData,
            QualifiedMember dictionaryEntryMember,
            IObjectMappingData mappingData,
            IEnumerable <Type> derivedSourceTypes,
            ICollection <ParameterExpression> typedVariables,
            ICollection <Expression> mappingExpressions)
        {
            var sourceElement  = loopData.GetSourceElementValue();
            var mapNextElement = Expression.Continue(loopData.ContinueLoopTarget);

            var orderedDerivedSourceTypes = derivedSourceTypes
                                            .OrderBy(t => t, TypeComparer.MostToLeastDerived);

            foreach (var derivedSourceType in orderedDerivedSourceTypes)
            {
                var derivedSourceCheck      = new DerivedSourceTypeCheck(derivedSourceType);
                var typedVariableAssignment = derivedSourceCheck.GetTypedVariableAssignment(sourceElement);

                typedVariables.Add(derivedSourceCheck.TypedVariable);
                mappingExpressions.Add(typedVariableAssignment);

                var derivedTypeMapping    = GetDerivedTypeMapping(derivedSourceCheck, mappingData);
                var derivedTypePopulation = GetPopulation(derivedTypeMapping, dictionaryEntryMember, mappingData);
                var incrementCounter      = _wrappedBuilder.GetCounterIncrement();
                var derivedMappingBlock   = Expression.Block(derivedTypePopulation, incrementCounter, mapNextElement);
                var ifDerivedTypeReturn   = Expression.IfThen(derivedSourceCheck.TypeCheck, derivedMappingBlock);

                mappingExpressions.Add(ifDerivedTypeReturn);
            }
        }
        public Expression GetTargetObjectCreation(IObjectMappingData mappingData)
        {
            var cachedInfos = GetTargetObjectCreationInfos(mappingData, out var constructionKey);

            if (cachedInfos.None())
            {
                return(null);
            }

            constructionKey.MappingData = mappingData;
            constructionKey.Infos       = cachedInfos;

            var cachedConstruction = _constructionsCache.GetOrAdd(constructionKey, key =>
            {
                var constructions = key.Infos.ProjectToArray(info => info.ToConstruction());
                var construction  = Construction.For(constructions, key);

                key.AddSourceMemberTypeTesterIfRequired();
                key.MappingData = null;

                return(construction);
            });

            mappingData.MapperData.Context.UsesMappingDataObjectAsParameter = cachedConstruction.UsesMappingDataObjectParameter;

            var constructionExpression = cachedConstruction.GetConstruction(mappingData);

            return(constructionExpression);
        }
Beispiel #10
0
        public object MapRepeated(IObjectMappingData childMappingData)
        {
            var mapperFunc = _repeatedMappingFuncsByKey
                             .GetOrAdd(childMappingData.MapperKey, null);

            return(mapperFunc.Map(childMappingData));
        }
Beispiel #11
0
        public ObjectMapper(
            Expression <MapperFunc <TSource, TTarget> > mappingLambda,
            IObjectMappingData mappingData)
        {
            _mapperKey    = mappingData.MapperKey;
            MappingLambda = mappingLambda;
            MapperData    = mappingData.MapperData;

            if (MapperData.Context.Compile)
            {
                _mapperFunc = mappingLambda.Compile();
            }
            else if (MapperData.Context.NeedsSubMapping)
            {
                MapperData.Mapper = this;
            }

            if (MapperData.Context.NeedsSubMapping)
            {
                _subMappersByKey = MapperData.MapperContext.Cache.CreateNew <ObjectMapperKeyBase, IObjectMapper>();
            }

            if (MapperData.HasRepeatedMapperFuncs)
            {
                _repeatedMappingFuncsByKey = MapperData.MapperContext.Cache.CreateNew <ObjectMapperKeyBase, IRepeatedMapperFunc>();
                MapperData.Mapper          = this;

                CacheRepeatedMappingFuncs();
            }
        }
        private static void AddDerivedTargetTypeDataSources(
            IEnumerable <Type> derivedTargetTypes,
            IObjectMappingData declaredTypeMappingData,
            ICollection <IDataSource> derivedTypeDataSources)
        {
            var declaredTypeMapperData = declaredTypeMappingData.MapperData;

            if (((ICollection <Type>)derivedTargetTypes).Count > 1)
            {
                derivedTargetTypes = derivedTargetTypes.OrderBy(t => t, MostToLeastDerived);
            }

            foreach (var derivedTargetType in derivedTargetTypes)
            {
                var targetTypeCondition = declaredTypeMapperData.GetTargetIsDerivedTypeCheck(derivedTargetType);

                var derivedTypeMapping = GetReturnMappingResultExpression(
                    declaredTypeMappingData,
                    declaredTypeMapperData.SourceObject,
                    derivedTargetType,
                    out var derivedTypeMappingData);

                if (derivedTypeMapping == EmptyExpression)
                {
                    continue;
                }

                var derivedTargetTypeDataSource = new DerivedComplexTypeDataSource(
                    derivedTypeMappingData.MapperData.SourceMember,
                    targetTypeCondition,
                    derivedTypeMapping);

                derivedTypeDataSources.Add(derivedTargetTypeDataSource);
            }
        }
        public static Expression GetDerivedTypeMapping(
            IObjectMappingData declaredTypeMappingData,
            Expression sourceValue,
            Type targetType,
            out IObjectMappingData derivedTypeMappingData)
        {
            derivedTypeMappingData = declaredTypeMappingData.WithTypes(sourceValue.Type, targetType);

            var declaredTypeMapperData = declaredTypeMappingData.MapperData;

            if (DerivedSourceTypeIsUnconditionallyIgnored(derivedTypeMappingData))
            {
                return(declaredTypeMapperData.TargetObject.GetConversionTo(targetType));
            }

            var targetValue = declaredTypeMapperData.TargetMember.IsReadable
                ? declaredTypeMapperData.TargetObject.GetConversionTo(targetType)
                : targetType.ToDefaultExpression();

            if (declaredTypeMappingData.IsRoot)
            {
                return(GetDerivedTypeRootMapping(derivedTypeMappingData, sourceValue, targetValue));
            }

            if (declaredTypeMapperData.TargetMemberIsEnumerableElement())
            {
                return(MappingFactory.GetElementMapping(derivedTypeMappingData, sourceValue, targetValue));
            }

            return(GetDerivedTypeChildMapping(derivedTypeMappingData, sourceValue, targetValue));
        }
        protected override Expression GetNewObjectCreation(IObjectMappingData mappingData, IList <Expression> memberPopulations)
        {
            var objectCreation = base.GetNewObjectCreation(mappingData, memberPopulations);

            if (objectCreation == null)
            {
                memberPopulations.Clear();
            }

            if (memberPopulations.None())
            {
                return(objectCreation);
            }

            var memberBindings = GetMemberBindingsFrom(memberPopulations);

            if (memberBindings.None())
            {
                return(objectCreation);
            }

            var objectNewings      = NewExpressionFinder.FindIn(objectCreation);
            var newingReplacements = new Dictionary <Expression, Expression>(objectNewings.Count);

            foreach (var objectNewing in objectNewings)
            {
                var objectInit = Expression.MemberInit(objectNewing, memberBindings);

                newingReplacements.Add(objectNewing, objectInit);
            }

            var fullObjectInit = objectCreation.Replace(newingReplacements);

            return(fullObjectInit);
        }
Beispiel #15
0
        public Expression GetPopulation(
            EnumerablePopulationBuilder builder,
            IObjectMappingData enumerableMappingData)
        {
            if (builder.ElementTypesAreSimple)
            {
                builder.AssignSourceVariableFrom(s => s.SourceItemsProjectedToTargetType().ExcludingTargetItems());
                builder.AssignTargetVariable();
                builder.AddNewItemsToTargetVariable(enumerableMappingData);

                return(builder);
            }

            if (builder.ElementsAreIdentifiable)
            {
                builder.CreateCollectionData();
                builder.MapIntersection(enumerableMappingData);
                builder.AssignSourceVariableFrom(s => s.CollectionDataNewSourceItems());
                builder.AssignTargetVariable();
                builder.AddNewItemsToTargetVariable(enumerableMappingData);

                return(builder);
            }

            builder.AssignSourceVariableFromSourceObject();
            builder.AssignTargetVariable();
            builder.AddNewItemsToTargetVariable(enumerableMappingData);

            return(builder);
        }
        private IList <IConstructionInfo> GetTargetObjectCreationInfos(
            IObjectMappingData mappingData,
            out ConstructionKey constructionKey)
        {
            return(_constructionInfosCache.GetOrAdd(constructionKey = new ConstructionKey(mappingData), key =>
            {
                IList <IConstructionInfo> constructionInfos = new List <IConstructionInfo>();

                AddConfiguredConstructionInfos(
                    constructionInfos,
                    key,
                    out var otherConstructionRequired);

                if (otherConstructionRequired && !key.MappingData.MapperData.TargetType.IsAbstract())
                {
                    AddAutoConstructionInfos(constructionInfos, key);
                }

                key.AddSourceMemberTypeTesterIfRequired();
                key.MappingData = null;

                return constructionInfos.None()
                    ? Enumerable <IConstructionInfo> .EmptyArray
                    : constructionInfos;
            }));
        }
        protected override IEnumerable <Expression> GetShortCircuitReturns(IObjectMappingData mappingData)
        {
            var mapperData = mappingData.MapperData;

            if (SourceObjectCouldBeNull(mapperData))
            {
                var returnNull = Expression.Return(
                    mapperData.ReturnLabelTarget,
                    mapperData.TargetType.ToDefaultExpression());

                yield return(Expression.IfThen(mapperData.SourceObject.GetIsDefaultComparison(), returnNull));
            }

            var alreadyMappedShortCircuit = GetAlreadyMappedObjectShortCircuitOrNull(mapperData);

            if (alreadyMappedShortCircuit != null)
            {
                yield return(alreadyMappedShortCircuit);
            }

            if (TryGetShortCircuitFactory(mapperData, out var sourceShortCircuitFactory))
            {
                yield return(sourceShortCircuitFactory.GetShortCircuit(mappingData));
            }
        }
Beispiel #18
0
        public static Expression GetInlineMappingBlock(
            IObjectMappingData mappingData,
            MappingValues mappingValues,
            Expression createMappingDataCall)
        {
            var mapper = mappingData.GetOrCreateMapper();

            if (mapper == null)
            {
                if (mappingData.HasSameTypedConfiguredDataSource())
                {
                    // Configured data source for an otherwise-unconstructable complex type:
                    return(mappingValues.SourceValue);
                }

                return(Constants.EmptyExpression);
            }

            var mapperData = mapper.MapperData;

            if (mapperData.Context.UsesMappingDataObject)
            {
                return(UseLocalValueVariable(
                           mapperData.MappingDataObject,
                           createMappingDataCall,
                           mapper.MappingExpression,
                           mapperData));
            }

            return(GetDirectAccessMapping(
                       mapper.MappingLambda.Body,
                       mapperData,
                       mappingValues,
                       createMappingDataCall));
        }
Beispiel #19
0
        protected override bool TargetCannotBeMapped(IObjectMappingData mappingData, out Expression nullMappingBlock)
        {
            if (mappingData.MapperData.TargetCouldBePopulated())
            {
                // If a target complex type is readonly or unconstructable
                // we still try to map to it using an existing non-null value:
                return(base.TargetCannotBeMapped(mappingData, out nullMappingBlock));
            }

            if (mappingData.MapperData.MapperContext.ConstructionFactory.GetNewObjectCreation(mappingData) != null)
            {
                return(base.TargetCannotBeMapped(mappingData, out nullMappingBlock));
            }

            var targetType = mappingData.MapperData.TargetType;

            if (targetType.IsAbstract() && mappingData.MapperData.GetDerivedTargetTypes().Any())
            {
                return(base.TargetCannotBeMapped(mappingData, out nullMappingBlock));
            }

            nullMappingBlock = Expression.Block(
                ReadableExpression.Comment("Cannot construct an instance of " + targetType.GetFriendlyName()),
                targetType.ToDefaultExpression());

            return(true);
        }
        private static IMemberPopulation Create(Member targetMember, IObjectMappingData mappingData)
        {
            var qualifiedMember = mappingData.MapperData.TargetMember.Append(targetMember);
            var childMapperData = new ChildMemberMapperData(qualifiedMember, mappingData.MapperData);

            Expression populateCondition;

            if (TargetMemberIsUnconditionallyIgnored(childMapperData, out populateCondition))
            {
                return(MemberPopulation.IgnoredMember(childMapperData));
            }

            var childMappingData = mappingData.GetChildMappingData(childMapperData);

            var dataSources = childMapperData
                              .MapperContext
                              .DataSources
                              .FindFor(childMappingData);

            if (dataSources.None)
            {
                return(MemberPopulation.NoDataSource(childMapperData));
            }

            return(new MemberPopulation(childMapperData, dataSources, populateCondition));
        }
Beispiel #21
0
        private static Expression GetParameterlessDictionaryAssignment(IObjectMappingData mappingData)
        {
            var helper        = mappingData.MapperData.EnumerablePopulationBuilder.TargetTypeHelper;
            var newDictionary = helper.GetEmptyInstanceCreation();

            return(GetDictionaryAssignment(newDictionary, mappingData));
        }
Beispiel #22
0
        public override bool IsFor(IObjectMappingData mappingData)
        {
            var mapperData = mappingData.MapperData;

            return(mapperData.IsRoot &&
                   mapperData.TargetMember.IsEnumerable &&
                   mapperData.SourceType.IsQueryable());
        }
 private static Expression GetFallbackValue(IObjectMappingData mappingData)
 {
     return(mappingData.MappingContext
            .RuleSet
            .FallbackDataSourceFactory
            .Create(mappingData.MapperData)
            .Value);
 }
 public static IList <IBasicConstructionInfo> GetTargetObjectCreationInfos(this IObjectMappingData mappingData)
 {
     return(mappingData
            .MapperData
            .MapperContext
            .ConstructionFactory
            .GetTargetObjectCreationInfos(mappingData));
 }
Beispiel #25
0
 public override IMembersSource GetMembersSource(IObjectMappingData parentMappingData)
 {
     return(_childMemberSource ?? (_childMemberSource =
                                       new MemberLookupsChildMembersSource(
                                           parentMappingData,
                                           _targetMemberRegistrationName,
                                           _dataSourceIndex)));
 }
Beispiel #26
0
        public IDataSource CreateFor(IObjectMappingData mappingData)
        {
            var mappingExpression = _mappingExpressionFactory.Create(mappingData);

            return(new AdHocDataSource(
                       mappingData.MapperData.SourceMember,
                       mappingExpression));
        }
        private Expression AssignDictionaryEntry(IPopulationLoopData loopData, IObjectMappingData mappingData)
        {
            loopData.NeedsContinueTarget = true;

            var dictionaryEntryMember = _targetDictionaryMember.GetElementMember();

            return(AssignDictionaryEntry(loopData, dictionaryEntryMember, mappingData));
        }
Beispiel #28
0
 public static Expression GetTargetObjectCreation(this IObjectMappingData mappingData)
 {
     return(mappingData
            .MapperData
            .MapperContext
            .ConstructionFactory
            .GetNewObjectCreation(mappingData));
 }
        public static Expression Create(EnumerablePopulationBuilder builder, IObjectMappingData enumerableMappingData)
        {
            builder.AssignSourceVariableFromSourceObject();
            builder.AssignTargetVariable();
            builder.AddNewItemsToTargetVariable(enumerableMappingData);

            return(builder);
        }
        public Expression GetPopulation(
            EnumerablePopulationBuilder builder,
            IObjectMappingData enumerableMappingData)
        {
            builder.PopulateTargetVariableFromSourceObjectOnly(enumerableMappingData);

            return(builder);
        }