protected CompositeModelInfo ResolveModelInfo( SetQuery <CompositeModelInfo> set, IEnumerable <Type> types ) { CompositeModelInfo result = null; CompositeModelInfo[] modelInfos = set.Where(kvp => types.All(type => kvp.Model.PublicTypes.Any(pType => type.IsAssignableFrom(pType) || (type.IsGenericType() && pType.Equals(type.GetGenericTypeDefinition()))))).Select(kvp => kvp).ToArray(); if (modelInfos.Length > 0) { if (modelInfos.Length == 1) { result = modelInfos[0]; } else { result = modelInfos.FirstOrDefault(info => types.All(type => info.Model.PublicTypes.Contains(type))); if (result == null) { throw new AmbiguousTypeException(types, modelInfos.Select(info => info.Model.PublicTypes)); } } } if (result == null) { throw new NoSuchCompositeTypeException(types); } return(result); }
public CompositeModelInfo GetCompositeModelInfo(CompositeModelType modelType, IEnumerable <Type> compositeTypes) { ArgumentValidator.ValidateNotNull("Composite model type", modelType); ArgumentValidator.ValidateNotNull("Composite types", compositeTypes); CompositeModelInfo result = null; SetQuery <CompositeModelInfo> dic = null; if (this._compositeModels.TryGetValue(modelType, out dic)) { result = this.ResolveModelInfo(dic, compositeTypes); } return(result); }
protected CompositeInstanceImpl( CompositeInstanceStructureOwner structureOwner, CompositeModel model, IEnumerable <Type> publicCompositeTypes, UsesContainerQuery usesContainer, MainCompositeConstructorArguments publicCtorArgsObject ) { ArgumentValidator.ValidateNotNull("Structure owner", structureOwner); ArgumentValidator.ValidateNotNull("Composite model", model); ArgumentValidator.ValidateNotEmpty("Composite type", publicCompositeTypes); ArgumentValidator.ValidateNotNull("Container for objects to be used in fragment creation", usesContainer); this._structureOwner = structureOwner; var application = this._structureOwner.Application; this._modelInfo = this._structureOwner.ModelInfoContainer.GetCompositeModelInfo(model); if (publicCompositeTypes.Any(pcType => pcType.ContainsGenericParameters())) { throw new InternalException("With given public composite types {" + String.Join(", ", publicCompositeTypes) + "} and public composite type in model being [" + String.Join(", ", model.PublicTypes) + "], the public composite types contained non-closed generic parameters."); } this._usesContainer = usesContainer; this._isPrototype = (Int32)PrototypeState.PROTOTYPE; this._invocationInfos = new Lazy <ThreadLocal <Stack <InvocationInfo> > >(() => new ThreadLocal <Stack <InvocationInfo> >(() => new Stack <InvocationInfo>()), LazyThreadSafetyMode.PublicationOnly); var composites = application.CollectionsFactory.NewDictionaryProxy <Type, Object>(); var cProps = application.CollectionsFactory.NewListProxy(new List <CompositeProperty>(model.Methods.Count * 2)); var cEvents = application.CollectionsFactory.NewListProxy(new List <CompositeEvent>(model.Methods.Count * 2)); var publicTypeGenResult = this._modelInfo.Types; var factory = publicTypeGenResult.CompositeFactory; var gArgs = publicTypeGenResult.PublicCompositeGenericArguments.Count == 0 ? null : new Type[publicTypeGenResult.GeneratedMainPublicType.GetGenericArguments().Length]; this._gArgs = gArgs; foreach (var pType in publicCompositeTypes) { ListQuery <Int32> gArgInfo = null; if (publicTypeGenResult.PublicCompositeGenericArguments.TryGetValue(pType.GetGenericDefinitionIfGenericType(), out gArgInfo)) { var declaredGArgs = pType.GetGenericArguments(); for (Int32 i = 0; i < declaredGArgs.Length; ++i) { gArgs[gArgInfo[i]] = declaredGArgs[i]; } } } if (gArgs != null && gArgs.Any(gArg => gArg == null)) { throw new InvalidCompositeTypeException(publicCompositeTypes, "Could not find suitable generic argument for all public types of composite " + this._modelInfo.Model + "."); } Action prePrototypeAction = null; var publicCtorArgs = new Object[publicTypeGenResult.MaxParamCountForCtors]; Object[] compositeCtorParams = null; foreach (var genType in publicTypeGenResult.GeneratedPublicTypes) { var isMainType = genType.GeneratedType.Equals(this._modelInfo.Types.GeneratedMainPublicType); var curCtorArgs = isMainType ? publicCtorArgs : compositeCtorParams; this.SetCompositeCtorArgs(ref curCtorArgs, cProps.AO, cEvents.AO); var publicComposite = factory.CreateInstance(genType.GeneratedTypeID, gArgs, curCtorArgs); foreach (var cType in this.GetTypeKeysForGeneratedType(publicComposite.GetType(), true, isMainType)) { composites[cType] = publicComposite; } if (isMainType) { if (publicCtorArgsObject != null) { publicCtorArgsObject.Arguments = curCtorArgs; } prePrototypeAction = (Action)publicCtorArgs[COMPOSITE_CTOR_FIRST_ADDITIONAL_PARAM_IDX]; this._prototypeAction = (Action)publicCtorArgs[COMPOSITE_CTOR_FIRST_ADDITIONAL_PARAM_IDX + 1]; this._checkStateFunc = (Action <IDictionary <QualifiedName, IList <ConstraintViolationInfo> > >)publicCtorArgs[COMPOSITE_CTOR_FIRST_ADDITIONAL_PARAM_IDX + 2]; this._compositeMethods = new Lazy <MethodInfo[]>(() => ((CompositeCallbacks)publicComposite).GetCompositeMethods(), LazyThreadSafetyMode.ExecutionAndPublication); } } this._isPrototypeTransitionInProgress = null; this.SetCompositeCtorArgs(ref compositeCtorParams, cProps.AO, cEvents.AO); foreach (var typeGenResult in publicTypeGenResult.PrivateCompositeGenerationResults) { var privateComposite = factory.CreateInstance(typeGenResult.GeneratedTypeID, gArgs, compositeCtorParams); foreach (var cTypeOrParent in this.GetTypeKeysForGeneratedType(privateComposite.GetType(), false, false)) { composites.Add(cTypeOrParent, privateComposite); } } this._composites = composites.CQ; this._methodsToModels = new Lazy <DictionaryQuery <MethodInfo, CompositeMethodModel> >(() => { var retVal = new Dictionary <MethodInfo, CompositeMethodModel>(); var cMethods = this._compositeMethods.Value; for (var i = 0; i < cMethods.Length; ++i) { var cm = cMethods[i]; retVal.Add(cm, this._modelInfo.Model.Methods[i]); } return(application.CollectionsFactory.NewDictionaryProxy(retVal).CQ); }, LazyThreadSafetyMode.ExecutionAndPublication); this._state = new CompositeStateImpl(this._structureOwner.Application.CollectionsFactory, cProps.CQ, cEvents.CQ); this._fragmentInstancePools = this.CreatePoolDictionary <FragmentTypeGenerationResult, FragmentInstance>( gArgs, this._modelInfo.Types.FragmentGenerationResults.Where(fGenResult => fGenResult.InstancePoolRequired), application.CollectionsFactory); var fInstances = application.CollectionsFactory.NewDictionaryProxy(new Dictionary <Type, FragmentInstance>()); foreach (var genResult in publicTypeGenResult.FragmentGenerationResults.Where(val => !val.InstancePoolRequired)) { var genType = genResult.GeneratedType; if (gArgs != null) { genType = genType.MakeGenericType(gArgs); } else if (genType.ContainsGenericParameters()) { throw new InternalException("Could not find generic arguments for fragment type " + genResult.DeclaredType + "."); } fInstances.Add(genType, new FragmentInstanceImpl()); } this._fragmentInstances = fInstances.CQ; this._concernInvocationInstances = this.CreatePoolDictionary <TypeGenerationResult, FragmentDependant>(gArgs, publicTypeGenResult.ConcernInvocationGenerationResults, application.CollectionsFactory); this._sideEffectInvocationInstances = this.CreatePoolDictionary <TypeGenerationResult, FragmentDependant>(gArgs, publicTypeGenResult.SideEffectGenerationResults, application.CollectionsFactory); this._constructorsForFragments = application.CollectionsFactory.NewDictionaryProxy <Type, ListQuery <FragmentConstructorInfo> >(this._fragmentInstancePools.Keys.Concat(this._fragmentInstances.Keys) .ToDictionary( fType => fType, fType => application.CollectionsFactory.NewListProxy(fType .GetAllInstanceConstructors() .Select(fCtor => { Int32 idx; return(fCtor.TryGetConstructorModelIndex(out idx) ? new FragmentConstructorInfo(model.Constructors[idx], fCtor) : null); }) .Where(i => i != null) .ToList() ).CQ )).CQ; if (prePrototypeAction != null) { prePrototypeAction(); } }