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;
            }));
        }
        private static void AddConfiguredConstructionInfos(
            ICollection <IConstructionInfo> constructionInfos,
            ConstructionKey key,
            out bool otherConstructionRequired)
        {
            var mapperData = key.MappingData.MapperData;

            var configuredFactories = mapperData
                                      .MapperContext
                                      .UserConfigurations
                                      .QueryObjectFactories(mapperData);

            foreach (var configuredFactory in configuredFactories)
            {
                var configuredConstructionInfo = new ConfiguredFactoryInfo(configuredFactory, mapperData);

                constructionInfos.Add(configuredConstructionInfo);

                if (configuredConstructionInfo.IsUnconditional)
                {
                    otherConstructionRequired = false;
                    return;
                }
            }

            otherConstructionRequired = true;
        }
        private static void AddConfiguredConstructions(
            ICollection <Construction> constructions,
            ConstructionKey key,
            out bool otherConstructionRequired)
        {
            var mapperData = key.MappingData.MapperData;

            otherConstructionRequired = true;

            var configuredFactories = mapperData
                                      .MapperContext
                                      .UserConfigurations
                                      .GetObjectFactories(mapperData);

            foreach (var configuredFactory in configuredFactories)
            {
                var configuredConstruction = new Construction(configuredFactory, mapperData);

                constructions.Add(configuredConstruction);

                if (configuredConstruction.IsUnconditional)
                {
                    otherConstructionRequired = false;
                    return;
                }
            }
        }
Exemplo n.º 4
0
        public void GetOrCreateConstructorCall_CacheMiss()
        {
            var typeID = AssembledTypeIDObjectMother.Create();

            _typeCacheMock
            .Setup(
                mock => mock.GetOrCreateType(
                    // Use strongly typed Equals overload.
                    It.Is <AssembledTypeID> (id => id.Equals(typeID))))
            .Returns(_assembledType)
            .Verifiable();

            _constructorDelegateFactoryMock
            .Setup(mock => mock.CreateConstructorCall(typeID.RequestedType, _assembledType, _delegateType, _allowNonPublic))
            .Returns(_generatedCtorCall)
            .Verifiable();

            var result = _constructorCallCache.GetOrCreateConstructorCall(typeID, _delegateType, _allowNonPublic);

            Assert.That(result, Is.SameAs(_generatedCtorCall));

            var key = new ConstructionKey(typeID, _delegateType, _allowNonPublic);

            Assert.That(_constructorCalls[key], Is.SameAs(_generatedCtorCall));
        }
        private static void AddAutoConstructions(IList <Construction> constructions, ConstructionKey key)
        {
            var mapperData = key.MappingData.MapperData;

            var greediestAvailableFactories   = GetGreediestAvailableFactories(key);
            var greediestUnconditionalFactory = greediestAvailableFactories.LastOrDefault(f => f.IsUnconditional);

            var constructors = mapperData.TargetInstance.Type
                               .GetPublicInstanceConstructors()
                               .ToArray();

            var greediestAvailableNewings = constructors.Any()
                ? GetGreediestAvailableNewings(constructors, key, greediestUnconditionalFactory)
                : Enumerable <ConstructionData <ConstructorInfo> > .EmptyArray;

            int i;

            for (i = 0; i < greediestAvailableFactories.Length; i++)
            {
                greediestAvailableFactories[i].AddTo(constructions, key);
            }

            for (i = 0; i < greediestAvailableNewings.Length; i++)
            {
                greediestAvailableNewings[i].AddTo(constructions, key);
            }

            if (constructions.None() && mapperData.TargetMemberIsUserStruct())
            {
                constructions.Add(Construction.NewStruct(mapperData.TargetInstance.Type));
            }
        }
            public static Construction For(IList <Construction> constructions, ConstructionKey key)
            {
                var construction = constructions.HasOne()
                    ? constructions.First()
                    : new Construction(constructions);

                return(construction.With(key));
            }
        public Expression GetFactoryMethodObjectCreationOrNull(IObjectMappingData mappingData)
        {
            var key         = new ConstructionKey(mappingData);
            var factoryData = GetGreediestAvailableFactories(key);

            return(factoryData.Any()
                ? factoryData.First().Construction.With(key).GetConstruction(mappingData)
                : null);
        }
        private static ConstructionDataInfo <ConstructorInfo>[] GetGreediestAvailableNewingInfos(
            IEnumerable <ConstructorInfo> constructors,
            ConstructionKey key,
            IBasicConstructionInfo greediestUnconditionalFactoryInfo)
        {
            var candidateConstructors = constructors
                                        .Filter(greediestUnconditionalFactoryInfo, IsCandidateCtor);

            return(CreateConstructionInfo(candidateConstructors, ctor => new ObjectNewingInfo(ctor, key)));
        }
Exemplo n.º 9
0
        public void SetUp()
        {
            var typeID1 = new AssembledTypeID(typeof(int), new object[0]);
            var typeID2 = new AssembledTypeID(typeof(object), new object[0]);

            _key1 = new ConstructionKey(typeID1, typeof(Action), true);
            _key2 = new ConstructionKey(typeID2, typeof(Action), true);
            _key3 = new ConstructionKey(typeID1, typeof(Func <int>), true);
            _key4 = new ConstructionKey(typeID1, typeof(Action), false);
            _key5 = new ConstructionKey(typeID1, typeof(Action), true);
        }
        private static ConstructionData <ConstructorInfo>[] GetGreediestAvailableNewings(
            IEnumerable <ConstructorInfo> constructors,
            ConstructionKey key,
            ConstructionData <MethodInfo> greediestUnconditionalFactory)
        {
            var candidateConstructors = constructors
                                        .Filter(ctor => IsCandidateCtor(ctor, greediestUnconditionalFactory));

            return(CreateConstructionData(
                       candidateConstructors,
                       ctor => new ConstructionData <ConstructorInfo>(ctor, Expression.New, key, priority: 0)));
        }
            public static Construction For(IList <Construction> constructions, ConstructionKey key)
            {
                if (constructions.HasOne())
                {
                    return(constructions.First().With(key));
                }

                var construction = new Construction(
                    ReverseChain(constructions),
                    usesMappingDataObjectParameter: constructions.Any(c => c.UsesMappingDataObjectParameter));

                return(construction.With(key));
            }
            public void AddTo(IList <Construction> constructions, ConstructionKey key)
            {
                if (ParameterCount > 0)
                {
                    var dataSources = key.MappingData.MapperData.DataSourcesByTargetMember;

                    foreach (var memberAndDataSourceSet in _argumentDataSources.Filter(ads => !dataSources.ContainsKey(ads.Item1)))
                    {
                        dataSources.Add(memberAndDataSourceSet.Item1, memberAndDataSourceSet.Item2);
                    }
                }

                constructions.AddSorted(Construction);
            }
            public void AddTo(IList <IConstructionInfo> constructionInfos, ConstructionKey key)
            {
                if (ParameterCount > 0)
                {
                    var mapperData = key.MappingData.MapperData;

                    for (var i = 0; i < ParameterCount; ++i)
                    {
                        mapperData.MergeTargetMemberDataSources(
                            _argumentTargetMembers[i],
                            ArgumentDataSources[i]);
                    }
                }

                constructionInfos.AddThenSort(this);
            }
            public void AddTo(IList <IConstructionInfo> constructionInfos, ConstructionKey key)
            {
                if (ParameterCount > 0)
                {
                    var dataSources = key.MappingData.MapperData.DataSourcesByTargetMember;

                    var relevantDataSourceSets = ArgumentDataSources
                                                 .Filter(dataSources, (dss, ds) => !dss.ContainsKey(ds.MapperData.TargetMember));

                    foreach (var dataSourceSet in relevantDataSourceSets)
                    {
                        dataSources.Add(dataSourceSet.MapperData.TargetMember, dataSourceSet);
                    }
                }

                constructionInfos.AddThenSort(this);
            }
            protected ConstructionDataInfo(
                TInvokable invokable,
                ConstructionKey key,
                int priority)
            {
                ArgumentDataSources = GetArgumentDataSources(invokable, key);
                CanBeInvoked        = ArgumentDataSources.All(ds => ds.HasValue);
                ParameterCount      = ArgumentDataSources.Length;
                Priority            = priority;

                if (!CanBeInvoked)
                {
                    return;
                }

                IsUnconditional = !ArgumentDataSources.Any(ds => ds.IsConditional && ds.MapperData.TargetMember.IsComplex);
            }
            protected ConstructionDataInfo(
                TInvokable invokable,
                ConstructionKey key,
                int priority)
            {
                var parameters = invokable.GetParameters();

                Priority               = priority;
                ParameterCount         = parameters.Length;
                _argumentTargetMembers = new QualifiedMember[ParameterCount];
                ArgumentDataSources    = new IDataSourceSet[ParameterCount];

                CanBeInvoked = IsUnconditional = true;
                var mappingData = key.MappingData;
                var mapperData  = mappingData.MapperData;

                for (var i = 0; i < ParameterCount; ++i)
                {
                    var argumentMember = Member.ConstructorParameter(parameters[i]);

                    var targetMember = _argumentTargetMembers[i] =
                        mapperData.TargetMember.Append(argumentMember);

                    var argumentMapperData  = new ChildMemberMapperData(targetMember, mapperData);
                    var argumentMappingData = mappingData.GetChildMappingData(argumentMapperData);

                    var dataSources = ArgumentDataSources[i] = MemberDataSourceSetFactory
                                                               .CreateFor(new DataSourceFindContext(argumentMappingData));

                    if (CanBeInvoked && !dataSources.HasValue)
                    {
                        CanBeInvoked = false;
                    }

                    if (IsUnconditional && dataSources.IsConditional && argumentMember.IsComplex)
                    {
                        IsUnconditional = false;
                    }
                }
            }
        private static void AddAutoConstructionInfos(IList <IConstructionInfo> constructionInfos, ConstructionKey key)
        {
            var mapperData = key.MappingData.MapperData;

            var greediestAvailableFactoryInfos    = GetGreediestAvailableFactoryInfos(key);
            var greediestUnconditionalFactoryInfo = greediestAvailableFactoryInfos.LastOrDefault(f => f.IsUnconditional);

            var constructors = mapperData.TargetInstance.Type
                               .GetPublicInstanceConstructors()
                               .ToArray();

            int i;

            for (i = 0; i < greediestAvailableFactoryInfos.Length; ++i)
            {
                greediestAvailableFactoryInfos[i].AddTo(constructionInfos, key);
            }

            if (constructors.Any())
            {
                var greediestAvailableNewingInfos = GetGreediestAvailableNewingInfos(
                    constructors,
                    key,
                    greediestUnconditionalFactoryInfo);

                for (i = 0; i < greediestAvailableNewingInfos.Length; ++i)
                {
                    greediestAvailableNewingInfos[i].AddTo(constructionInfos, key);
                }
            }

            if (constructionInfos.None() && mapperData.TargetMemberIsUserStruct())
            {
                constructionInfos.Add(new StructInfo(mapperData.TargetInstance.Type));
            }
        }
 public Construction(ICollection <Construction> constructions, ConstructionKey key)
     : this(constructions.ReverseChain())
 {
     UsesMappingDataObjectParameter = constructions.Any(c => c.UsesMappingDataObjectParameter);
     _mappingDataObject             = key.MappingData.MapperData.MappingDataObject;
 }
        private static ConstructionDataInfo <MethodInfo>[] GetGreediestAvailableFactoryInfos(ConstructionKey key)
        {
            var mapperData = key.MappingData.MapperData;

            var candidateFactoryMethods = mapperData.TargetInstance.Type
                                          .GetPublicStaticMethods()
                                          .Filter(mapperData.TargetInstance.Type, IsFactoryMethod);

            return(CreateConstructionInfo(candidateFactoryMethods, fm => new FactoryMethodInfo(fm, key)));
        }
 public ObjectNewingInfo(ConstructorInfo ctor, ConstructionKey key)
     : base(ctor, key, priority: 0)
 {
     _ctor           = ctor;
     _parameterNames = _ctor.GetParameters().ProjectToArray(p => p.Name);
 }
 public Construction With(ConstructionKey key)
 {
     _mappingDataObject = key.MappingData.MapperData.MappingDataObject;
     return(this);
 }
 public FactoryMethodInfo(MethodInfo factoryMethod, ConstructionKey key)
     : base(factoryMethod, key, priority: 1)
 {
     _factoryMethod = factoryMethod;
 }
            private static Tuple <QualifiedMember, DataSourceSet>[] GetArgumentDataSources(TInvokable invokable, ConstructionKey key)
            {
                return(invokable
                       .GetParameters()
                       .ProjectToArray(p =>
                {
                    var parameterMapperData = new ChildMemberMapperData(
                        key.MappingData.MapperData.TargetMember.Append(Member.ConstructorParameter(p)),
                        key.MappingData.MapperData);

                    var memberMappingData = key.MappingData.GetChildMappingData(parameterMapperData);
                    var dataSources = DataSourceFinder.FindFor(memberMappingData);

                    return Tuple.Create(memberMappingData.MapperData.TargetMember, dataSources);
                }));
            }
            public ConstructionData(
                TInvokable invokable,
                Func <TInvokable, IList <Expression>, Expression> constructionFactory,
                ConstructionKey key,
                int priority)
            {
                var argumentDataSources = GetArgumentDataSources(invokable, key);

                CanBeInvoked   = argumentDataSources.All(ds => ds.Item2.HasValue);
                ParameterCount = argumentDataSources.Length;
                Priority       = priority;

                if (!CanBeInvoked)
                {
                    return;
                }

                IsUnconditional = true;

                Expression constructionExpression;

                if (argumentDataSources.None())
                {
                    constructionExpression = constructionFactory.Invoke(invokable, Enumerable <Expression> .EmptyArray);
                    Construction           = new Construction(this, constructionExpression);
                    return;
                }

                _argumentDataSources = argumentDataSources;

                var variables      = default(List <ParameterExpression>);
                var argumentValues = new List <Expression>(ParameterCount);
                var condition      = default(Expression);

                foreach (var argumentDataSource in argumentDataSources)
                {
                    var dataSources = argumentDataSource.Item2;

                    if (dataSources.Variables.Any())
                    {
                        if (variables == null)
                        {
                            variables = new List <ParameterExpression>(dataSources.Variables);
                        }
                        else
                        {
                            variables.AddRange(dataSources.Variables);
                        }
                    }

                    argumentValues.Add(dataSources.ValueExpression);

                    if (!argumentDataSource.Item1.IsComplex || !dataSources.IsConditional)
                    {
                        continue;
                    }

                    IsUnconditional = false;

                    var dataSourceCondition = BuildConditions(dataSources);

                    if (condition == null)
                    {
                        condition = dataSourceCondition;
                        continue;
                    }

                    condition = Expression.AndAlso(condition, dataSourceCondition);
                }

                constructionExpression = constructionFactory.Invoke(invokable, argumentValues);

                Construction = variables.NoneOrNull()
                    ? new Construction(this, constructionExpression, condition)
                    : new Construction(this, Expression.Block(variables, constructionExpression), condition);
            }
            private static IDataSourceSet[] GetArgumentDataSources(TInvokable invokable, ConstructionKey key)
            {
                return(invokable
                       .GetParameters()
                       .ProjectToArray(key.MappingData, (mappingData, p) =>
                {
                    var parameterMapperData = new ChildMemberMapperData(
                        mappingData.MapperData.TargetMember.Append(Member.ConstructorParameter(p)),
                        mappingData.MapperData);

                    var memberMappingData = mappingData.GetChildMappingData(parameterMapperData);
                    var dataSources = DataSourceSetFactory.CreateFor(new DataSourceFindContext(memberMappingData));

                    return dataSources;
                }));
            }
        private static ConstructionData <MethodInfo>[] GetGreediestAvailableFactories(ConstructionKey key)
        {
            var mapperData = key.MappingData.MapperData;

            var candidateFactoryMethods = mapperData.TargetInstance.Type
                                          .GetPublicStaticMethods()
                                          .Filter(m => IsFactoryMethod(m, mapperData.TargetInstance.Type));

            return(CreateConstructionData(
                       candidateFactoryMethods,
                       fm => new ConstructionData <MethodInfo>(fm, Expression.Call, key, priority: 1)));
        }