private void DisconnectInstanceFromExport( PartCompositionId importingInstance, ImportRegistrationId importId, PartCompositionId exportingInstance) { var importingPartInfo = m_Parts[importingInstance]; if (importingPartInfo.Instance != null) { var importDefinition = importingPartInfo.Definition.Import(importId); if (importDefinition.IsPrerequisite) { ReleaseInstance(importingInstance); } else { var satisfiedPartImports = SatisfiedPartImports(importingInstance) .Where(p => !p.Item2.Equals(exportingInstance)); var partImports = ImportInformationForPart(satisfiedPartImports); var updatedInstances = Instances.UpdateIfRequired(importingPartInfo.Instance, partImports); foreach (var instance in updatedInstances) { if (instance.Change == InstanceChange.Removed) { var updatedInfo = m_Parts.FirstOrDefault(p => instance.Instance.Equals(p.Value.Instance)); updatedInfo.Value.Instance = null; } } } } }
/// <summary> /// Adds a new <see cref="GroupDefinition"/> to the graph and returns the ID for that group. /// </summary> /// <param name="id">The ID of the group that is being added.</param> /// <param name="group">The group that should be added to the graph.</param> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="id"/> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="group"/> is <see langword="null" />. /// </exception> public void Add(GroupCompositionId id, GroupDefinition group) { { Lokad.Enforce.Argument(() => id); Lokad.Enforce.Argument(() => group); } if (!m_Definitions.ContainsKey(group.Id)) { m_Definitions.Add(group.Id, group); } m_Groups.Add(id, group.Id); m_GroupConnections.AddVertex(id); foreach (var part in group.Parts) { var partId = new PartCompositionId(id, part.Id); m_Parts.Add(partId, new PartCompositionInfo(part)); m_PartConnections.AddVertex(partId); } var parts = PartsForGroup(id); ConnectParts(group.InternalConnections, parts, parts); }
public void Create() { var group = new GroupCompositionId(); var part = new PartRegistrationId("a", 1); var id = new PartCompositionId(group, part); Assert.AreEqual(group, id.Group); Assert.AreEqual(part, id.Part); }
private bool AreRequiredPartImportsSatisfied(PartCompositionId partId, IEnumerable <ImportRegistrationId> satisfiedRequiredImports) { var info = m_Parts[partId]; var unsatisfiedImports = info.Definition .RegisteredImports .Where(id => info.Definition.Import(id).IsPrerequisite) .Except(satisfiedRequiredImports); return(!unsatisfiedImports.Any()); }
private void DisconnectPartInstanceFromImportingParts(PartCompositionId partId) { var importingParts = m_PartConnections .OutEdges(partId) .Select(edge => new Tuple <PartCompositionId, ImportRegistrationId>(edge.Target, edge.ImportRegistration)); foreach (var pair in importingParts) { DisconnectInstanceFromExport(pair.Item1, pair.Item2, partId); } }
private bool CanPartBeInstantiated(PartCompositionId partId) { var info = m_Parts[partId]; if (info.Instance != null) { return(true); } var satisfiedPartImports = SatisfiedPartImports(partId); var satisfiedRequiredPartImports = satisfiedPartImports.Where(p => info.Definition.Import(p.Item1).IsPrerequisite); return(AreRequiredPartImportsSatisfied(partId, satisfiedRequiredPartImports.Select(p => p.Item1)) && CanPartsBeInstantiated(satisfiedRequiredPartImports.Select(p => p.Item2))); }
private void ReleaseInstance(PartCompositionId partId) { var info = m_Parts[partId]; if (info.Instance != null) { DisconnectPartInstanceFromImportingParts(partId); var updatedInstances = Instances.Release(info.Instance); foreach (var instance in updatedInstances) { if (instance.Change == InstanceChange.Removed) { var updatedInfo = m_Parts.FirstOrDefault(p => instance.Instance.Equals(p.Value.Instance)); updatedInfo.Value.Instance = null; } } } }
/// <summary> /// Removes the group that is related to the specified ID. /// </summary> /// <param name="group">The ID of the group that should be removed.</param> public void Remove(GroupCompositionId group) { if (group == null) { return; } if (!m_Groups.ContainsKey(group)) { return; } var definitionId = m_Groups[group]; var definition = m_Definitions[definitionId]; foreach (var part in definition.Parts) { var partId = new PartCompositionId(group, part.Id); Debug.Assert(m_Parts.ContainsKey(partId), "The part collection should have the given part ID."); Debug.Assert(m_PartConnections.ContainsVertex(partId), "The part connections graph should have the given part ID."); var info = m_Parts[partId]; if (info.Instance != null) { ReleaseInstance(partId); } m_PartConnections.RemoveVertex(partId); m_Parts.Remove(partId); } Debug.Assert(m_GroupConnections.ContainsVertex(group), "The connections graph should have the given group ID."); m_GroupConnections.RemoveVertex(group); m_Groups.Remove(group); if (!m_Groups.Any(p => p.Value.Equals(definitionId))) { m_Definitions.Remove(definitionId); } }
private void ConstructInstance(PartCompositionId partId) { if (CanPartBeInstantiated(partId)) { var satisfiedPartImports = SatisfiedPartImports(partId); foreach (var importPair in satisfiedPartImports) { var exportingPartInfo = m_Parts[importPair.Item2]; if (exportingPartInfo.Instance == null) { ConstructInstance(importPair.Item2); } } var partImports = ImportInformationForPart(satisfiedPartImports); var info = m_Parts[partId]; if (info.Instance != null) { var updatedInstances = Instances.UpdateIfRequired(info.Instance, partImports); foreach (var instance in updatedInstances) { if (instance.Change == InstanceChange.Removed) { var updatedInfo = m_Parts.FirstOrDefault(p => instance.Instance.Equals(p.Value.Instance)); updatedInfo.Value.Instance = null; } } } else { info.Instance = Instances.Construct( info.Definition, partImports); } } }
private IEnumerable <Tuple <ImportRegistrationId, PartCompositionId, ExportRegistrationId> > SatisfiedPartImports(PartCompositionId partId) { return(m_PartConnections .InEdges(partId) .Select( edge => new Tuple <ImportRegistrationId, PartCompositionId, ExportRegistrationId>( edge.ImportRegistration, edge.Source, edge.ExportRegistration))); }