using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Servit.Framework { public class TopologicalSort { public delegate IEnumerable GetDependentTypes(T item, IEnumerable potentialDependencies); public static IEnumerable PerformTopoSort(IEnumerable items, GetDependentTypes getDependentTypes) { var list = new List>(); var nodes = items.Select(i => new Node(i)).ToList(); nodes.ForEach(n => Visit(n, nodes, list, getDependentTypes)); return list.Select(n => n.Value); } public class Node { public T Value { get; private set; } public bool Visited { get; set; } public Node(T value) { this.Value = value; } } private static void Visit(Node node, IEnumerable> nodes, IList> sorted, GetDependentTypes getDependentItems) { if (node.Visited) { return; } node.Visited = true; var dependentItems = getDependentItems(node.Value, nodes.Select(l => l.Value)); var dependentNodes = from i in dependentItems join n in nodes on i equals n.Value select n; foreach (Node dependency in dependentNodes) { Visit(dependency, nodes, sorted, getDependentItems); } sorted.Insert(0, node); return; } } }