Пример #1
0
        /// <summary>
        /// Orders elements of a linearized directed graph in a dependency order, while preserving the original order
        /// between elements with no dependencies.
        /// </summary>
        public static IEnumerable <T> Order <T>(
            IEnumerable <T> itemsToOrder,
            TopologicalDependencyFunction <T> dependencyFunction)
        {
            if (itemsToOrder == null)
            {
                throw new ArgumentNullException(nameof(itemsToOrder));
            }
            if (dependencyFunction == null)
            {
                throw new ArgumentNullException(nameof(dependencyFunction));
            }

            var itemsToOrderList = itemsToOrder.ToList();

            if (itemsToOrderList.Count < 2)
            {
                return(itemsToOrder);
            }

            int itemsToOrderCount = itemsToOrderList.Count;

            var graph = DependencyGraph <T> .TryCreate(itemsToOrderList, dependencyFunction, EqualityComparer <T> .Default);

            if (graph == null)
            {
                return(itemsToOrder);
            }

Restart:
            for (int i = 0; i < itemsToOrderCount; ++i)
            {
                for (int j = 0; j < i; ++j)
                {
                    if (graph.DoesXHaveDirectDependencyOnY(itemsToOrderList[j], itemsToOrderList[i]))
                    {
                        bool jDependsOnI = graph.DoesXHaveTransientDependencyOnY(itemsToOrderList[j], itemsToOrderList[i]);
                        bool iDependsOnJ = graph.DoesXHaveTransientDependencyOnY(itemsToOrderList[i], itemsToOrderList[j]);

                        bool circularDependency = jDependsOnI && iDependsOnJ;

                        if (!circularDependency)
                        {
                            var t = itemsToOrderList[i];
                            itemsToOrderList.RemoveAt(i);

                            itemsToOrderList.Insert(j, t);
                            goto Restart;
                        }
                    }
                }
            }

            return(itemsToOrderList);
        }
Пример #2
0
            public static DependencyGraph <T> TryCreate(
                IList <T> items,
                TopologicalDependencyFunction <T> dependencyFunction,
                IEqualityComparer <T> equalityComparer)
            {
                var graph = new DependencyGraph <T>(equalityComparer, items.Count);

                bool hasDependencies = false;

                for (int position = 0; position < items.Count; ++position)
                {
                    var element = items[position];

                    if (!graph.Nodes.TryGetValue(element, out Node node))
                    {
                        node = new Node();
                        graph.Nodes.Add(element, node);
                    }

                    foreach (var anotherElement in items)
                    {
                        if (equalityComparer.Equals(element, anotherElement))
                        {
                            continue;
                        }

                        if (dependencyFunction(element, anotherElement))
                        {
                            node.Children.Add(anotherElement);
                            hasDependencies = true;
                        }
                    }
                }

                if (!hasDependencies)
                {
                    return(null);
                }

                return(graph);
            }