private void InitRequirements(ComponentRequirementMap map) { this.Requirements = new List <Type>(); IEnumerable <RequiredComponentAttribute> attribs = this.Component.GetTypeInfo().GetAttributesCached <RequiredComponentAttribute>(); foreach (RequiredComponentAttribute a in attribs) { Type reqType = a.RequiredComponentType; // Don't require itself if (reqType == this.Component) { continue; } // Ignore invalid constraints if (!this.IsValidRequirement(a)) { continue; } this.Requirements.AddRange(map.GetRequirements(reqType).Where(t => !this.Requirements.Contains(t))); if (!this.Requirements.Contains(reqType)) { this.Requirements.Add(reqType); } } }
private void InitCreationChain(ComponentRequirementMap map) { this.CreationChain = new List <CreationChainItem>(); IEnumerable <RequiredComponentAttribute> attributes = this.Component.GetTypeInfo().GetAttributesCached <RequiredComponentAttribute>(); foreach (RequiredComponentAttribute attrib in attributes) { // Ignore invalid constraints if (!this.IsValidRequirement(attrib)) { continue; } // If this is a conditional creation, add the sub-chain of the Component to create if (attrib.CreateDefaultType != attrib.RequiredComponentType) { this.AddCreationChainElements(map, attrib, attrib.CreateDefaultType); } // In any case, add the sub-chain of direct requirements this.AddCreationChainElements(map, attrib, attrib.RequiredComponentType); } // Remove any duplicates that we might have generated in the creation chain this.RemoveCreationChainDuplicates(); }
public void EnsureCreationChain(ComponentRequirementMap map) { if (this.initCreationChain == RecursiveInit.Initialized) { return; } if (this.initCreationChain == RecursiveInit.InProgress) { Logs.Core.WriteWarning( "Detected a cyclic Component requirement in {0}. Requirements can not be ensured for cyclic dependencies.", LogFormat.Type(this.Component)); return; } this.initCreationChain = RecursiveInit.InProgress; this.InitCreationChain(map); this.initCreationChain = RecursiveInit.Initialized; }
private void AddCreationChainElements(ComponentRequirementMap map, RequiredComponentAttribute attrib, Type subChainType) { if (subChainType == this.Component) { return; } int baseIndex = this.CreationChain.Count; int subChainLength = 0; // Retrieve the creation sub-chain to satisfy this item's requirements List <CreationChainItem> createTypeSubChain = map.GetCreationChain(subChainType); foreach (CreationChainItem subItem in createTypeSubChain) { this.CreationChain.Add(subItem); subChainLength++; } // Add the main item after its requirement items so we're always creating bottom-up this.CreationChain.Add(new CreationChainItem { RequiredType = attrib.RequiredComponentType, CreateType = attrib.CreateDefaultType }); // If this is a conditional requirement, add a control item that checks the // requirement and skips this item and its sub-chains if it's already met. if (subChainLength > 0 && attrib.CreateDefaultType != attrib.RequiredComponentType) { this.CreationChain.Insert(baseIndex, new CreationChainItem { RequiredType = attrib.RequiredComponentType, SkipIfExists = 1 + subChainLength }); } }