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; } } }
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))); }
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))); }