public static ComponentGraph FromComponents(IEnumerable <string> components, IDictionary <string, string> elements, IDictionary <string, ComponentGraph> modules) { ComponentGraph graph = new ComponentGraph(); Dictionary <string, ComponentVertex> vertices = new Dictionary <string, ComponentVertex>(); foreach (string component in components) { IList <string> parts = ComponentGraph.SplitArchitecture(component, NetworkGraphBuilder.Splitter); if (parts.Count >= 2 && parts.All(x => !string.IsNullOrEmpty(x))) { ComponentVertex sourceVertex = null; ComponentGraph sourceGraph = null; for (int i = 0, ii = parts.Count; i < ii; i++) { string key = parts[i]; ComponentGraph targetGraph = null; if (key.First() == NetworkGraphBuilder.StartQualifier && key.Last() == NetworkGraphBuilder.EndQualifier) { targetGraph = NetworkGraphBuilder.ParseArchitecture(key.Substring(1, key.Length - 2), true); } else { ComponentGraph moduleGraph; if (modules.TryGetValue(key, out moduleGraph)) { targetGraph = moduleGraph.Clone(true) as ComponentGraph; } } if (targetGraph != null) { if (i > 0) { bool result = sourceVertex != null?ComponentGraph.AddEdge(graph, sourceVertex, targetGraph) : ComponentGraph.AddEdge(graph, sourceGraph, targetGraph); if (!result) { throw new ArgumentException( string.Format(CultureInfo.InvariantCulture, Properties.Resources.E_InvalidNetArchitecture_DuplicateEdge, parts[i - 1], parts[i])); } } sourceVertex = null; sourceGraph = targetGraph; } else { ComponentVertex targetVertex; string arch; if (elements.TryGetValue(key, out arch)) { if (!vertices.TryGetValue(key, out targetVertex)) { vertices[key] = targetVertex = new ComponentVertex(key, arch); } } else { targetVertex = new ComponentVertex(Guid.NewGuid().ToString(), key); } if (i > 0) { bool result = sourceVertex != null?ComponentGraph.AddEdge(graph, sourceVertex, targetVertex) : ComponentGraph.AddEdge(graph, sourceGraph, targetVertex); if (!result) { throw new ArgumentException( string.Format(CultureInfo.InvariantCulture, Properties.Resources.E_InvalidNetArchitecture_DuplicateEdge, parts[i - 1], parts[i])); } } sourceVertex = targetVertex; sourceGraph = null; } } } else if (parts.Count == 1 && !string.IsNullOrEmpty(parts[0])) { graph.AddVertex(new ComponentVertex(Guid.NewGuid().ToString(), parts[0])); } else { throw new ArgumentException( string.Format(CultureInfo.InvariantCulture, Properties.Resources.E_InvalidNetArchitecture, component)); } } // recreate vertices keys, for the embedded graphs to have unique layers foreach (ComponentVertex vertex in graph.Vertices) { vertex.Key = Guid.NewGuid().ToString(); } return(graph); }