public bool CanConnectTo( GroupCompositionId importingGroup, GroupImportDefinition importDefinition, IDictionary <string, object> selectionCriteria, GroupCompositionId exportingGroup) { if (!m_Graph.Contains(importingGroup)) { return(false); } if (!m_Graph.Contains(exportingGroup)) { return(false); } if (m_Graph.IsConnected(importingGroup, importDefinition)) { return(false); } var group = m_Graph.Group(exportingGroup); return(m_GroupImportEngine.Accepts(importDefinition, group.GroupExport) && m_GroupImportEngine.ExportPassesSelectionCriteria(group.GroupExport, selectionCriteria)); }
private static GroupDefinition CreateImportingGroup() { return(new GroupDefinition("b") { InternalConnections = Enumerable.Empty <PartImportToPartExportMap>(), Parts = new List <GroupPartDefinition> { new GroupPartDefinition( TypeIdentity.CreateDefinition(typeof(string)), 0, new Dictionary <ExportRegistrationId, SerializableExportDefinition>(), new Dictionary <ImportRegistrationId, SerializableImportDefinition> { { new ImportRegistrationId(typeof(string), 0, "PartContract1"), PropertyBasedImportDefinition.CreateDefinition( "PartContract1", TypeIdentity.CreateDefinition(typeof(int)), ImportCardinality.ExactlyOne, false, CreationPolicy.Any, typeof(ImportOnPropertyWithType).GetProperty("ImportingProperty")) } }, new Dictionary <ScheduleActionRegistrationId, ScheduleActionDefinition>(), new Dictionary <ScheduleConditionRegistrationId, ScheduleConditionDefinition>()), new GroupPartDefinition( TypeIdentity.CreateDefinition(typeof(string)), 1, new Dictionary <ExportRegistrationId, SerializableExportDefinition>(), new Dictionary <ImportRegistrationId, SerializableImportDefinition> { { new ImportRegistrationId(typeof(string), 1, "PartContract2"), PropertyBasedImportDefinition.CreateDefinition( "PartContract2", TypeIdentity.CreateDefinition(typeof(string)), ImportCardinality.ExactlyOne, false, CreationPolicy.Any, typeof(ImportOnPropertyWithEnumerable).GetProperty("ImportingProperty")) } }, new Dictionary <ScheduleActionRegistrationId, ScheduleActionDefinition>(), new Dictionary <ScheduleConditionRegistrationId, ScheduleConditionDefinition>()), }, GroupImports = new List <GroupImportDefinition> { GroupImportDefinition.CreateDefinition( "ContractName", new GroupRegistrationId("b"), null, new List <ImportRegistrationId> { new ImportRegistrationId(typeof(string), 0, "PartContract1"), new ImportRegistrationId(typeof(string), 1, "PartContract2"), }) }, }); }
public void ConnectWithUnknownExportingGroup() { using (var source = new CancellationTokenSource()) { var commands = new Mock <ICompositionCommands>(); { commands.Setup(c => c.Add(It.IsAny <GroupCompositionId>(), It.IsAny <GroupDefinition>())) .Returns( Task.Factory.StartNew( () => { }, source.Token, TaskCreationOptions.None, new CurrentThreadTaskScheduler())); } var connector = new Mock <IConnectGroups>(); var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var layer = new ProxyCompositionLayer(commands.Object, connector.Object, systemDiagnostics); var exportingGroup = new GroupDefinition("Group1"); var task = layer.Add(exportingGroup); task.Wait(); var importDefinition = GroupImportDefinition.CreateDefinition( "a", new GroupRegistrationId("b"), null, Enumerable.Empty <ImportRegistrationId>()); Assert.Throws <UnknownPartGroupException>(() => layer.Connect(task.Result, importDefinition, new GroupCompositionId())); } }
public void Connect() { using (var source = new CancellationTokenSource()) { var commands = new Mock <ICompositionCommands>(); { commands.Setup(c => c.Add(It.IsAny <GroupCompositionId>(), It.IsAny <GroupDefinition>())) .Returns( Task.Factory.StartNew( () => { }, source.Token, TaskCreationOptions.None, new CurrentThreadTaskScheduler())); commands.Setup(c => c.Connect(It.IsAny <GroupConnection>())) .Returns( Task.Factory.StartNew( () => { }, source.Token, TaskCreationOptions.None, new CurrentThreadTaskScheduler())); } var connector = new Mock <IConnectGroups>(); { connector.Setup( c => c.GenerateConnectionFor( It.IsAny <GroupDefinition>(), It.IsAny <GroupImportDefinition>(), It.IsAny <GroupDefinition>())) .Callback <GroupDefinition, GroupImportDefinition, GroupDefinition>( (importingGroup, importDef, exportingGroup) => { }) .Returns(Enumerable.Empty <PartImportToPartExportMap>()); } var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var layer = new ProxyCompositionLayer(commands.Object, connector.Object, systemDiagnostics); var exportingDefinition = new GroupDefinition("Group1"); var addTask = layer.Add(exportingDefinition); var exportingId = addTask.Result; var importingDefinition = new GroupDefinition("Group2"); addTask = layer.Add(importingDefinition); var importingId = addTask.Result; var importDefinition = GroupImportDefinition.CreateDefinition( "a", new GroupRegistrationId("b"), null, Enumerable.Empty <ImportRegistrationId>()); var connectTask = layer.Connect(importingId, importDefinition, exportingId); connectTask.Wait(); Assert.IsTrue(layer.IsConnected(importingId, importDefinition)); Assert.IsTrue(layer.IsConnected(importingId, importDefinition, exportingId)); Assert.AreEqual(exportingId, layer.ConnectedTo(importingId, importDefinition)); } }
public void ReloadFromDataset() { var importingId = new GroupCompositionId(); var exportingId = new GroupCompositionId(); var importingGroup = new GroupDefinition("Group1"); var exportingGroup = new GroupDefinition("Group2"); var importDefinition = GroupImportDefinition.CreateDefinition( "a", new GroupRegistrationId("b"), null, Enumerable.Empty <ImportRegistrationId>()); var state = new GroupCompositionState( new List <Tuple <GroupCompositionId, GroupDefinition> > { new Tuple <GroupCompositionId, GroupDefinition>(importingId, importingGroup), new Tuple <GroupCompositionId, GroupDefinition>(exportingId, exportingGroup), }, new List <Tuple <GroupCompositionId, GroupImportDefinition, GroupCompositionId> > { new Tuple <GroupCompositionId, GroupImportDefinition, GroupCompositionId>(importingId, importDefinition, exportingId) }); using (var source = new CancellationTokenSource()) { var commands = new Mock <ICompositionCommands>(); { commands.Setup(c => c.CurrentState()) .Returns( Task <GroupCompositionState> .Factory.StartNew( () => state, source.Token, TaskCreationOptions.None, new CurrentThreadTaskScheduler())); } var connector = new Mock <IConnectGroups>(); var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var layer = new ProxyCompositionLayer(commands.Object, connector.Object, systemDiagnostics); var task = layer.ReloadFromDataset(); task.Wait(); Assert.IsTrue(layer.Contains(importingId)); Assert.AreEqual(importingGroup, layer.Group(importingId)); Assert.IsTrue(layer.Contains(exportingId)); Assert.AreEqual(exportingGroup, layer.Group(exportingId)); Assert.IsTrue(layer.IsConnected(importingId, importDefinition)); Assert.IsTrue(layer.IsConnected(importingId, importDefinition, exportingId)); Assert.AreEqual(exportingId, layer.ConnectedTo(importingId, importDefinition)); } }
/// <summary> /// Returns a collection containing all the groups which satisfy the given group import and match the given /// selection criteria. /// </summary> /// <param name="groupToLinkTo">The import definition which should be satisfied.</param> /// <param name="selectionCriteria">The collection containing all the selection filters.</param> /// <returns> /// A collection containing all the groups which satisfy the given group import and match the given /// selection criteria. /// </returns> public IEnumerable <GroupDescriptor> MatchingGroups(GroupImportDefinition groupToLinkTo, IDictionary <string, object> selectionCriteria) { return(m_GroupImportEngine.MatchingGroups(groupToLinkTo, selectionCriteria) .Select( g => new GroupDescriptor( g, OnGroupSelect, OnGroupDeselect, OnGroupConnect, OnGroupDisconnect))); }
/// <summary> /// Initializes a new instance of the <see cref="CompositionLayerGroupEdge"/> class. /// </summary> /// <param name="importingGroup">The ID of the importing group.</param> /// <param name="importDefinition">The import definition.</param> /// <param name="exportingGroup">The ID of the exporting group.</param> public CompositionLayerGroupEdge( GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup) : base(exportingGroup, importingGroup) { { Debug.Assert(importDefinition != null, "The import definition should not be a null reference."); } m_Import = importDefinition; }
private Task OnGroupConnect( GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup, GroupExportDefinition exportDefinition) { if (!m_GroupImportEngine.Accepts(importDefinition, exportDefinition)) { throw new CannotMapExportToImportException(); } return(m_Graph.Connect(importingGroup, importDefinition, exportingGroup)); }
public bool Accepts(GroupImportDefinition importDefinition, GroupExportDefinition exportDefinition) { if (importDefinition == null) { return(true); } if (!string.Equals(importDefinition.ContractName, exportDefinition.ContractName, StringComparison.OrdinalIgnoreCase)) { return(false); } var importingGroup = m_Repository.Group(importDefinition.ContainingGroup); var exportingGroup = m_Repository.Group(exportDefinition.ContainingGroup); var isMatch = true; if (exportingGroup.Schedule != null) { isMatch = importDefinition.ScheduleInsertPosition != null; } if (isMatch) { var imports = importDefinition.ImportsToMatch.Select(i => importingGroup.Parts.PartImportById(i)); var exports = exportDefinition.ProvidedExports.Select(e => exportingGroup.Parts.PartExportById(e)); foreach (var import in imports) { var foundMatch = false; foreach (var export in exports) { if (m_PartImportEngine.Accepts(import, export)) { foundMatch = true; } } isMatch = isMatch && foundMatch; if (!isMatch) { break; } } } return(isMatch); }
public bool Accepts(GroupImportDefinition importDefinition, GroupExportDefinition exportDefinition) { if (importDefinition == null) { return true; } if (!string.Equals(importDefinition.ContractName, exportDefinition.ContractName, StringComparison.OrdinalIgnoreCase)) { return false; } var importingGroup = m_Repository.Group(importDefinition.ContainingGroup); var exportingGroup = m_Repository.Group(exportDefinition.ContainingGroup); var isMatch = true; if (exportingGroup.Schedule != null) { isMatch = importDefinition.ScheduleInsertPosition != null; } if (isMatch) { var imports = importDefinition.ImportsToMatch.Select(i => importingGroup.Parts.PartImportById(i)); var exports = exportDefinition.ProvidedExports.Select(e => exportingGroup.Parts.PartExportById(e)); foreach (var import in imports) { var foundMatch = false; foreach (var export in exports) { if (m_PartImportEngine.Accepts(import, export)) { foundMatch = true; } } isMatch = isMatch && foundMatch; if (!isMatch) { break; } } } return isMatch; }
public bool IsConnected(GroupCompositionId importingGroup, GroupImportDefinition importDefinition) { if ((importingGroup == null) || (importDefinition == null)) { return(false); } if (!Contains(importingGroup)) { return(false); } lock (m_Lock) { return(m_GroupConnections.InEdges(importingGroup).Any(e => e.Import.Equals(importDefinition))); } }
public void ConnectedToWithUnknownImportingGroup() { var commands = new Mock <ICompositionCommands>(); var connector = new Mock <IConnectGroups>(); var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null); var layer = new ProxyCompositionLayer(commands.Object, connector.Object, systemDiagnostics); var importDefinition = GroupImportDefinition.CreateDefinition( "a", new GroupRegistrationId("b"), null, Enumerable.Empty <ImportRegistrationId>()); Assert.IsNull(layer.ConnectedTo(null, importDefinition)); Assert.IsNull(layer.ConnectedTo(new GroupCompositionId(), null)); Assert.IsNull(layer.ConnectedTo(new GroupCompositionId(), importDefinition)); }
/// <summary> /// Initializes a new instance of the <see cref="GroupConnection"/> class. /// </summary> /// <param name="importingGroup">The ID of the group that provides the import.</param> /// <param name="exportingGroup">The ID of the group that provides the export.</param> /// <param name="import">The import definition that should be connected to.</param> /// <param name="partConnections">The collection that contains the mapping of the part imports to the part exports.</param> public GroupConnection( GroupCompositionId importingGroup, GroupCompositionId exportingGroup, GroupImportDefinition import, IEnumerable<PartImportToPartExportMap> partConnections) { { Lokad.Enforce.Argument(() => importingGroup); Lokad.Enforce.Argument(() => exportingGroup); Lokad.Enforce.Argument(() => import); Lokad.Enforce.Argument(() => partConnections); } m_ImportingGroup = importingGroup; m_ExportingGroup = exportingGroup; m_Import = import; m_PartConnections = partConnections; }
public void CanConnectToWithNonExistingExportGroup() { var importingId = new GroupCompositionId(); var exportingId = new GroupCompositionId(); var importEngine = new Mock <IConnectGroups>(); var graph = new Mock <ICompositionLayer>(); { graph.Setup(g => g.Contains(It.IsAny <GroupCompositionId>())) .Returns <GroupCompositionId>(id => !id.Equals(exportingId)); } var selector = new GroupSelector(importEngine.Object, graph.Object); Assert.IsFalse( selector.CanConnectTo( importingId, GroupImportDefinition.CreateDefinition("myContract", new GroupRegistrationId("a"), null, null), exportingId)); }
/// <summary> /// Creates the connection data that describes how the importing group and the exporting group should be connected. /// </summary> /// <param name="importingGroup">The ID of the group containing the import.</param> /// <param name="importDefinition">The import definition.</param> /// <param name="exportingGroup">The ID of the group containing the export.</param> /// <returns>A collection that describes how the parts of the importing and exporting group should be connected.</returns> public IEnumerable <PartImportToPartExportMap> GenerateConnectionFor( GroupDefinition importingGroup, GroupImportDefinition importDefinition, GroupDefinition exportingGroup) { if ((importingGroup == null) || (importDefinition == null) || (exportingGroup == null)) { return(Enumerable.Empty <PartImportToPartExportMap>()); } var importDefinitions = importDefinition .ImportsToMatch .Select(id => new Tuple <ImportRegistrationId, SerializableImportDefinition>(id, importingGroup.Parts.PartImportById(id))); var exportDefinitions = exportingGroup .GroupExport .ProvidedExports .Select(id => new Tuple <ExportRegistrationId, SerializableExportDefinition>(id, exportingGroup.Parts.PartExportById(id))) .ToList(); var parts = new List <PartImportToPartExportMap>(); foreach (var pair in importDefinitions) { var matchedExports = new List <Tuple <ExportRegistrationId, SerializableExportDefinition> >(); foreach (var export in exportDefinitions) { if (m_PartImportEngine.Accepts(pair.Item2, export.Item2)) { matchedExports.Add(export); } } parts.Add(new PartImportToPartExportMap(pair.Item1, matchedExports.Select(p => p.Item1).ToList())); foreach (var export in matchedExports) { exportDefinitions.Remove(export); } } return(parts); }
/// <summary> /// Registers a group with the currently stored data. /// </summary> /// <param name="name">The name of the newly created group.</param> /// <returns>The registration ID of the group.</returns> public GroupRegistrationId Register(string name) { var definition = new GroupDefinition(name); definition.Parts = m_Objects.SelectMany(p => p.Value).ToList(); definition.InternalConnections = m_Connections.Select( p => new PartImportToPartExportMap(p.Key, (IEnumerable <ExportRegistrationId>)p.Value)); if (m_Schedule != null) { definition.Schedule = ScheduleDefinition.CreateDefinition( definition.Id, m_Schedule, m_Actions.ToDictionary(p => p.Value, p => p.Key), m_Conditions.ToDictionary(p => p.Value, p => p.Key)); } if (m_GroupExport != null) { definition.GroupExport = GroupExportDefinition.CreateDefinition( m_GroupExport.ContractName, definition.Id, NonLinkedExports()); } if (m_GroupImports.Count > 0) { definition.GroupImports = m_GroupImports.Select( i => GroupImportDefinition.CreateDefinition( i.Value.ContractName, definition.Id, i.Value.InsertPoint, i.Value.ObjectImports)) .ToList(); } Clear(); m_Repository.AddGroup(definition, m_FileInfo); return(definition.Id); }
public void MatchingGroupsWithGroupImport() { var groups = new List <GroupDefinition> { new GroupDefinition("Group1"), new GroupDefinition("Group2"), new GroupDefinition("Group3"), }; var importEngine = new Mock <IConnectGroups>(); { importEngine.Setup(i => i.MatchingGroups(It.IsAny <GroupImportDefinition>(), It.IsAny <IDictionary <string, object> >())) .Returns(new List <GroupDefinition> { groups[0], groups[1] }); } var selector = new GroupSelector(importEngine.Object, new Mock <ICompositionLayer>().Object); var selectedGroups = selector.MatchingGroups(GroupImportDefinition.CreateDefinition("myContract", groups[0].Id, null, null)); Assert.AreEqual(2, selectedGroups.Count()); }
public void Connect() { var lockKey = new DatasetLockKey(); var datasetLock = new Mock <ITrackDatasetLocks>(); { datasetLock.Setup(d => d.LockForWriting()) .Returns(lockKey) .Verifiable(); datasetLock.Setup(d => d.RemoveWriteLock(It.IsAny <DatasetLockKey>())) .Callback <DatasetLockKey>(key => Assert.AreSame(lockKey, key)) .Verifiable(); } var originalConnection = new GroupConnection( new GroupCompositionId(), new GroupCompositionId(), GroupImportDefinition.CreateDefinition( "a", new GroupRegistrationId("a"), null, Enumerable.Empty <ImportRegistrationId>()), Enumerable.Empty <PartImportToPartExportMap>()); var storage = new Mock <IStoreGroupsAndConnections>(); { storage.Setup(s => s.Connect(It.IsAny <GroupConnection>())) .Callback <GroupConnection>( id => { Assert.AreSame(originalConnection, id); }); } var commands = new CompositionCommands(datasetLock.Object, storage.Object); var task = commands.Connect(originalConnection); task.Wait(); datasetLock.Verify(d => d.LockForWriting(), Times.Once()); datasetLock.Verify(d => d.RemoveWriteLock(It.IsAny <DatasetLockKey>()), Times.Once()); }
private void DisconnectParts(GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup) { var definitionId = m_Groups[importingGroup]; var importingGroupDefinition = m_Definitions[definitionId]; var importingParts = importDefinition .ImportsToMatch .Select(id => importingGroupDefinition.Parts.PartByImport(id)) .Join( m_Parts, partDef => new PartCompositionId(importingGroup, partDef.Id), pair => pair.Key, (partDef, pair) => pair.Key); definitionId = m_Groups[exportingGroup]; var exportingGroupDefinition = m_Definitions[definitionId]; var exportingParts = exportingGroupDefinition.GroupExport .ProvidedExports .Select(id => exportingGroupDefinition.Parts.PartByExport(id)) .Join( m_Parts, partDef => new PartCompositionId(exportingGroup, partDef.Id), pair => pair.Key, (partDef, pair) => pair.Key); foreach (var importingPart in importingParts) { var matchedExports = m_PartConnections .InEdges(importingPart) .Where(edge => exportingParts.Contains(edge.Source)) .Select(edge => new Tuple <ImportRegistrationId, PartCompositionId>(edge.ImportRegistration, edge.Source)); foreach (var pair in matchedExports) { DisconnectInstanceFromExport(importingPart, pair.Item1, pair.Item2); } m_PartConnections.RemoveInEdgeIf(importingPart, edge => exportingParts.Contains(edge.Source)); } }
/// <summary> /// Returns the group information indicating which export the given import is connected to. /// </summary> /// <param name="importingGroup">The ID of the group owning the import.</param> /// <param name="importDefinition">The import.</param> /// <returns>The ID of the group the given import is connected to, if there is a connection; otherwise, <see langword="null" />.</returns> public GroupCompositionId ConnectedTo( GroupCompositionId importingGroup, GroupImportDefinition importDefinition) { if ((importingGroup == null) || (importDefinition == null)) { return(null); } if (!Contains(importingGroup)) { return(null); } lock (m_Lock) { return(m_GroupConnections.InEdges(importingGroup) .Where(e => e.Import.Equals(importDefinition)) .Select(e => e.Source) .FirstOrDefault()); } }
/// <summary> /// Connects the given export to the given import. /// </summary> /// <param name="importingGroup">The ID of the group that owns the import.</param> /// <param name="importDefinition">The import.</param> /// <param name="exportingGroup">The ID of the group that owns the export.</param> /// <returns>A task which indicates when the connection has taken place.</returns> public Task Connect( GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup) { { Debug.Assert(importingGroup != null, "The ID of the importing group should not be a null reference."); Debug.Assert(importDefinition != null, "The import definition should not be a null reference."); Debug.Assert(exportingGroup != null, "The ID of the exporting group should not be a null reference."); } if (!Contains(importingGroup) || !Contains(exportingGroup)) { throw new UnknownPartGroupException(); } m_Diagnostics.Log( LevelToLog.Trace, HostConstants.LogPrefix, string.Format( CultureInfo.InvariantCulture, Resources.ProxyCompositionLayer_LogMessage_ConnectingGroups_WithImportAndExport, importingGroup, exportingGroup)); var parts = m_Connector.GenerateConnectionFor(m_Groups[importingGroup], importDefinition, m_Groups[exportingGroup]); var state = new GroupConnection(importingGroup, exportingGroup, importDefinition, parts); var remoteTask = m_Commands.Connect(state); return(remoteTask.ContinueWith( t => { lock (m_Lock) { m_GroupConnections.AddEdge(new CompositionLayerGroupEdge(importingGroup, importDefinition, exportingGroup)); } })); }
public void CanConnectToWithNonmatchingGroups() { var groups = new List <GroupDefinition> { new GroupDefinition("Group1"), new GroupDefinition("Group2"), new GroupDefinition("Group3"), }; var importEngine = new Mock <IConnectGroups>(); { importEngine.Setup(i => i.Accepts(It.IsAny <GroupImportDefinition>(), It.IsAny <GroupExportDefinition>())) .Returns(false); importEngine.Setup(i => i.ExportPassesSelectionCriteria(It.IsAny <GroupExportDefinition>(), It.IsAny <IDictionary <string, object> >())) .Returns(true); } var selector = new GroupSelector(importEngine.Object, new Mock <ICompositionLayer>().Object); Assert.IsFalse( selector.CanConnectTo( new GroupCompositionId(), GroupImportDefinition.CreateDefinition("myContract", groups[0].Id, null, null), new GroupCompositionId())); }
/// <summary> /// Returns a collection containing all the groups which provide an export that can satisfy the given group import. /// </summary> /// <param name="groupToLinkTo">The import definition which should be satisfied.</param> /// <returns>A collection containing all the groups which satisfy the import condition.</returns> public IEnumerable<GroupDescriptor> MatchingGroups(GroupImportDefinition groupToLinkTo) { return MatchingGroups(groupToLinkTo, new Dictionary<string, object>()); }
public bool IsConnected( GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup) { if ((importingGroup == null) || (importDefinition == null) || (exportingGroup == null)) { return false; } if (!Contains(importingGroup)) { return false; } lock (m_Lock) { return m_GroupConnections.InEdges(importingGroup).Any(e => e.Import.Equals(importDefinition) && e.Source.Equals(exportingGroup)); } }
/// <summary> /// Returns the group information indicating which export the given import is connected to. /// </summary> /// <param name="importingGroup">The ID of the group owning the import.</param> /// <param name="importDefinition">The import.</param> /// <returns>The ID of the group the given import is connected to, if there is a connection; otherwise, <see langword="null" />.</returns> public GroupCompositionId ConnectedTo( GroupCompositionId importingGroup, GroupImportDefinition importDefinition) { if ((importingGroup == null) || (importDefinition == null)) { return null; } if (!Contains(importingGroup)) { return null; } lock (m_Lock) { return m_GroupConnections.InEdges(importingGroup) .Where(e => e.Import.Equals(importDefinition)) .Select(e => e.Source) .FirstOrDefault(); } }
/// <summary> /// Creates the connection data that describes how the importing group and the exporting group should be connected. /// </summary> /// <param name="importingGroup">The ID of the group containing the import.</param> /// <param name="importDefinition">The import definition.</param> /// <param name="exportingGroup">The ID of the group containing the export.</param> /// <returns>A collection that describes how the parts of the importing and exporting group should be connected.</returns> public IEnumerable<PartImportToPartExportMap> GenerateConnectionFor( GroupDefinition importingGroup, GroupImportDefinition importDefinition, GroupDefinition exportingGroup) { if ((importingGroup == null) || (importDefinition == null) || (exportingGroup == null)) { return Enumerable.Empty<PartImportToPartExportMap>(); } var importDefinitions = importDefinition .ImportsToMatch .Select(id => new Tuple<ImportRegistrationId, SerializableImportDefinition>(id, importingGroup.Parts.PartImportById(id))); var exportDefinitions = exportingGroup .GroupExport .ProvidedExports .Select(id => new Tuple<ExportRegistrationId, SerializableExportDefinition>(id, exportingGroup.Parts.PartExportById(id))) .ToList(); var parts = new List<PartImportToPartExportMap>(); foreach (var pair in importDefinitions) { var matchedExports = new List<Tuple<ExportRegistrationId, SerializableExportDefinition>>(); foreach (var export in exportDefinitions) { if (m_PartImportEngine.Accepts(pair.Item2, export.Item2)) { matchedExports.Add(export); } } parts.Add(new PartImportToPartExportMap(pair.Item1, matchedExports.Select(p => p.Item1).ToList())); foreach (var export in matchedExports) { exportDefinitions.Remove(export); } } return parts; }
/// <summary> /// Connects the export of the current group to the given import of another group. /// </summary> /// <param name="group">The ID of the group containing the import.</param> /// <param name="importToMatch">The import.</param> /// <returns>The task that will finish once the give connection has been made.</returns> public Task ConnectTo(GroupCompositionId group, GroupImportDefinition importToMatch) { return m_OnConnect(group, importToMatch, m_Id, m_Group.GroupExport); }
/// <summary> /// Connects the export of the current group to the given import of another group. /// </summary> /// <param name="group">The ID of the group containing the import.</param> /// <param name="importToMatch">The import.</param> /// <returns>The task that will finish once the give connection has been made.</returns> public Task ConnectTo(GroupCompositionId group, GroupImportDefinition importToMatch) { return(m_OnConnect(group, importToMatch, m_Id, m_Group.GroupExport)); }
/// <summary> /// Returns a collection containing all the groups which provide an export that can satisfy the given group import. /// </summary> /// <param name="groupToLinkTo">The import definition which should be satisfied.</param> /// <returns>A collection containing all the groups which satisfy the import condition.</returns> public IEnumerable<GroupDefinition> MatchingGroups(GroupImportDefinition groupToLinkTo) { return MatchingGroups(groupToLinkTo, null); }
/// <summary> /// Returns a collection containing all the groups which provide an export that can satisfy the given group import. /// </summary> /// <param name="groupToLinkTo">The import definition which should be satisfied.</param> /// <returns>A collection containing all the groups which satisfy the import condition.</returns> public IEnumerable <GroupDefinition> MatchingGroups(GroupImportDefinition groupToLinkTo) { return(MatchingGroups(groupToLinkTo, null)); }
/// <summary> /// Returns a collection containing all the groups which satisfy the given group import and match the given /// selection criteria. /// </summary> /// <param name="groupToLinkTo">The import definition which should be satisfied.</param> /// <param name="selectionCriteria">The collection containing all the selection criteria.</param> /// <returns> /// A collection containing all the groups which satisfy the given group import and match the given /// selection criteria. /// </returns> public IEnumerable <GroupDefinition> MatchingGroups(GroupImportDefinition groupToLinkTo, IDictionary <string, object> selectionCriteria) { return(m_Repository.Groups() .Where(g => Accepts(groupToLinkTo, g.GroupExport) && ExportPassesSelectionCriteria(g.GroupExport, selectionCriteria))); }
private static GroupDefinition CreateImportingDefinition() { var groupName = "Import"; return(new GroupDefinition(groupName) { InternalConnections = Enumerable.Empty <PartImportToPartExportMap>(), Parts = new List <GroupPartDefinition> { new GroupPartDefinition( TypeIdentity.CreateDefinition(typeof(List <string>)), 0, new Dictionary <ExportRegistrationId, SerializableExportDefinition>(), new Dictionary <ImportRegistrationId, SerializableImportDefinition> { { new ImportRegistrationId(typeof(string), 0, "PartContract1"), PropertyBasedImportDefinition.CreateDefinition( "PartContract1", TypeIdentity.CreateDefinition(typeof(int)), ImportCardinality.ExactlyOne, false, CreationPolicy.Any, typeof(ImportOnPropertyWithType).GetProperty("ImportingProperty")) } }, new Dictionary <ScheduleActionRegistrationId, ScheduleActionDefinition>(), new Dictionary <ScheduleConditionRegistrationId, ScheduleConditionDefinition>()), new GroupPartDefinition( TypeIdentity.CreateDefinition(typeof(List <double>)), 1, new Dictionary <ExportRegistrationId, SerializableExportDefinition>(), new Dictionary <ImportRegistrationId, SerializableImportDefinition> { { new ImportRegistrationId(typeof(string), 1, "PartContract2"), ConstructorBasedImportDefinition.CreateDefinition( "PartContract2", TypeIdentity.CreateDefinition(typeof(string)), ImportCardinality.ExactlyOne, CreationPolicy.Any, typeof(Version).GetConstructor( new[] { typeof(string) }).GetParameters().First()) } }, new Dictionary <ScheduleActionRegistrationId, ScheduleActionDefinition>(), new Dictionary <ScheduleConditionRegistrationId, ScheduleConditionDefinition>()), }, GroupImports = new List <GroupImportDefinition> { GroupImportDefinition.CreateDefinition( "ContractName", new GroupRegistrationId(groupName), null, new List <ImportRegistrationId> { new ImportRegistrationId(typeof(string), 0, "PartContract1"), new ImportRegistrationId(typeof(string), 1, "PartContract2"), }) }, }); }
/// <summary> /// Returns a collection containing all the groups which provide an export that can satisfy the given group import. /// </summary> /// <param name="groupToLinkTo">The import definition which should be satisfied.</param> /// <returns>A collection containing all the groups which satisfy the import condition.</returns> public IEnumerable <GroupDescriptor> MatchingGroups(GroupImportDefinition groupToLinkTo) { return(MatchingGroups(groupToLinkTo, new Dictionary <string, object>())); }
public void CurrentState() { var lockKey = new DatasetLockKey(); var datasetLock = new Mock <ITrackDatasetLocks>(); { datasetLock.Setup(d => d.LockForReading()) .Returns(lockKey) .Verifiable(); datasetLock.Setup(d => d.RemoveReadLock(It.IsAny <DatasetLockKey>())) .Callback <DatasetLockKey>(key => Assert.AreSame(lockKey, key)) .Verifiable(); } var groups = new Dictionary <GroupCompositionId, Tuple <GroupDefinition, Tuple <GroupImportDefinition, GroupCompositionId> > > { { new GroupCompositionId(), new Tuple <GroupDefinition, Tuple <GroupImportDefinition, GroupCompositionId> >( new GroupDefinition("a"), new Tuple <GroupImportDefinition, GroupCompositionId>( GroupImportDefinition.CreateDefinition( "c", new GroupRegistrationId("c"), null, Enumerable.Empty <ImportRegistrationId>()), new GroupCompositionId())) }, { new GroupCompositionId(), new Tuple <GroupDefinition, Tuple <GroupImportDefinition, GroupCompositionId> >( new GroupDefinition("d"), new Tuple <GroupImportDefinition, GroupCompositionId>( GroupImportDefinition.CreateDefinition( "e", new GroupRegistrationId("e"), null, Enumerable.Empty <ImportRegistrationId>()), new GroupCompositionId())) }, }; var storage = new Mock <IStoreGroupsAndConnections>(); { storage.Setup(s => s.Groups()) .Returns(groups.Keys); storage.Setup(s => s.Group(It.IsAny <GroupCompositionId>())) .Returns <GroupCompositionId>(id => groups[id].Item1); storage.Setup(s => s.SatisfiedImports(It.IsAny <GroupCompositionId>())) .Returns <GroupCompositionId>(id => new List <Tuple <GroupImportDefinition, GroupCompositionId> > { groups[id].Item2 }); } var commands = new CompositionCommands(datasetLock.Object, storage.Object); var task = commands.CurrentState(); var results = task.Result; Assert.That( results.Groups, Is.EquivalentTo( groups.Select(p => new Tuple <GroupCompositionId, GroupDefinition>(p.Key, p.Value.Item1)))); Assert.That( results.Connections, Is.EquivalentTo( groups.Select( p => new Tuple <GroupCompositionId, GroupImportDefinition, GroupCompositionId>( p.Key, p.Value.Item2.Item1, p.Value.Item2.Item2)))); datasetLock.Verify(d => d.LockForReading(), Times.Once()); datasetLock.Verify(d => d.RemoveReadLock(It.IsAny <DatasetLockKey>()), Times.Once()); }
/// <summary> /// Connects the given export to the given import. /// </summary> /// <param name="importingGroup">The ID of the group that owns the import.</param> /// <param name="importDefinition">The import.</param> /// <param name="exportingGroup">The ID of the group that owns the export.</param> /// <returns>A task which indicates when the connection has taken place.</returns> public Task Connect( GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup) { { Debug.Assert(importingGroup != null, "The ID of the importing group should not be a null reference."); Debug.Assert(importDefinition != null, "The import definition should not be a null reference."); Debug.Assert(exportingGroup != null, "The ID of the exporting group should not be a null reference."); } if (!Contains(importingGroup) || !Contains(exportingGroup)) { throw new UnknownPartGroupException(); } m_Diagnostics.Log( LevelToLog.Trace, HostConstants.LogPrefix, string.Format( CultureInfo.InvariantCulture, Resources.ProxyCompositionLayer_LogMessage_ConnectingGroups_WithImportAndExport, importingGroup, exportingGroup)); var parts = m_Connector.GenerateConnectionFor(m_Groups[importingGroup], importDefinition, m_Groups[exportingGroup]); var state = new GroupConnection(importingGroup, exportingGroup, importDefinition, parts); var remoteTask = m_Commands.Connect(state); return remoteTask.ContinueWith( t => { lock (m_Lock) { m_GroupConnections.AddEdge(new CompositionLayerGroupEdge(importingGroup, importDefinition, exportingGroup)); } }); }
public bool CanConnectTo(GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup) { return CanConnectTo(importingGroup, importDefinition, new Dictionary<string, object>(), exportingGroup); }
/// <summary> /// Returns a collection containing all the groups which satisfy the given group import and match the given /// selection criteria. /// </summary> /// <param name="groupToLinkTo">The import definition which should be satisfied.</param> /// <param name="selectionCriteria">The collection containing all the selection filters.</param> /// <returns> /// A collection containing all the groups which satisfy the given group import and match the given /// selection criteria. /// </returns> public IEnumerable<GroupDescriptor> MatchingGroups(GroupImportDefinition groupToLinkTo, IDictionary<string, object> selectionCriteria) { return m_GroupImportEngine.MatchingGroups(groupToLinkTo, selectionCriteria) .Select( g => new GroupDescriptor( g, OnGroupSelect, OnGroupDeselect, OnGroupConnect, OnGroupDisconnect)); }
/// <summary> /// Returns a collection containing all the groups which satisfy the given group import and match the given /// selection criteria. /// </summary> /// <param name="groupToLinkTo">The import definition which should be satisfied.</param> /// <param name="selectionCriteria">The collection containing all the selection criteria.</param> /// <returns> /// A collection containing all the groups which satisfy the given group import and match the given /// selection criteria. /// </returns> public IEnumerable<GroupDefinition> MatchingGroups(GroupImportDefinition groupToLinkTo, IDictionary<string, object> selectionCriteria) { return m_Repository.Groups() .Where(g => Accepts(groupToLinkTo, g.GroupExport) && ExportPassesSelectionCriteria(g.GroupExport, selectionCriteria)); }
private Task OnGroupConnect( GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup, GroupExportDefinition exportDefinition) { if (!m_GroupImportEngine.Accepts(importDefinition, exportDefinition)) { throw new CannotMapExportToImportException(); } return m_Graph.Connect(importingGroup, importDefinition, exportingGroup); }
public bool CanConnectTo(GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup) { return(CanConnectTo(importingGroup, importDefinition, new Dictionary <string, object>(), exportingGroup)); }
public bool CanConnectTo( GroupCompositionId importingGroup, GroupImportDefinition importDefinition, IDictionary<string, object> selectionCriteria, GroupCompositionId exportingGroup) { if (!m_Graph.Contains(importingGroup)) { return false; } if (!m_Graph.Contains(exportingGroup)) { return false; } if (m_Graph.IsConnected(importingGroup, importDefinition)) { return false; } var group = m_Graph.Group(exportingGroup); return m_GroupImportEngine.Accepts(importDefinition, group.GroupExport) && m_GroupImportEngine.ExportPassesSelectionCriteria(group.GroupExport, selectionCriteria); }
private void DisconnectParts(GroupCompositionId importingGroup, GroupImportDefinition importDefinition, GroupCompositionId exportingGroup) { var definitionId = m_Groups[importingGroup]; var importingGroupDefinition = m_Definitions[definitionId]; var importingParts = importDefinition .ImportsToMatch .Select(id => importingGroupDefinition.Parts.PartByImport(id)) .Join( m_Parts, partDef => new PartCompositionId(importingGroup, partDef.Id), pair => pair.Key, (partDef, pair) => pair.Key); definitionId = m_Groups[exportingGroup]; var exportingGroupDefinition = m_Definitions[definitionId]; var exportingParts = exportingGroupDefinition.GroupExport .ProvidedExports .Select(id => exportingGroupDefinition.Parts.PartByExport(id)) .Join( m_Parts, partDef => new PartCompositionId(exportingGroup, partDef.Id), pair => pair.Key, (partDef, pair) => pair.Key); foreach (var importingPart in importingParts) { var matchedExports = m_PartConnections .InEdges(importingPart) .Where(edge => exportingParts.Contains(edge.Source)) .Select(edge => new Tuple<ImportRegistrationId, PartCompositionId>(edge.ImportRegistration, edge.Source)); foreach (var pair in matchedExports) { DisconnectInstanceFromExport(importingPart, pair.Item1, pair.Item2); } m_PartConnections.RemoveInEdgeIf(importingPart, edge => exportingParts.Contains(edge.Source)); } }