diff --git a/src/Orchard/Environment/State/ShellStateCoordinator.cs b/src/Orchard/Environment/State/ShellStateCoordinator.cs index 004ce0cc4..3cf5283c1 100644 --- a/src/Orchard/Environment/State/ShellStateCoordinator.cs +++ b/src/Orchard/Environment/State/ShellStateCoordinator.cs @@ -7,6 +7,7 @@ using Orchard.Environment.Extensions.Models; using Orchard.Environment.State.Models; using Orchard.Environment.Descriptor; using Orchard.Environment.Descriptor.Models; +using Orchard.Utility; namespace Orchard.Environment.State { public class ShellStateCoordinator : IShellStateManagerEventHandler, IShellDescriptorManagerEventHandler { @@ -184,39 +185,9 @@ namespace Orchard.Environment.State { state.EnableState == ShellFeatureState.State.Rising; } - class Linkage { - public FeatureDescriptor Feature { - get; - set; - } - public bool Used { - get; - set; - } - } - public static IEnumerable OrderByDependencies(IEnumerable descriptors) { - var population = descriptors.Select(d => new Linkage { - Feature = d - }).ToArray(); - - var result = new List(); - foreach (var item in population) { - Add(item, result, population); - } - return result; - } - - private static void Add(Linkage item, ICollection list, IEnumerable population) { - if (item.Used) - return; - - item.Used = true; - var dependencies = item.Feature.Dependencies ?? Enumerable.Empty(); - foreach (var dependency in dependencies.SelectMany(d => population.Where(p => p.Feature.Name == d))) { - Add(dependency, list, population); - } - list.Add(item.Feature); + return descriptors.OrderByDependencies((item, dep) => + item.Dependencies.Any(x => StringComparer.OrdinalIgnoreCase.Equals(x, dep.Name))); } } } diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index e736f8e98..cd6d7f761 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -402,6 +402,7 @@ + diff --git a/src/Orchard/Utility/DependencyOrderingUtility.cs b/src/Orchard/Utility/DependencyOrderingUtility.cs new file mode 100644 index 000000000..cf02d7e6e --- /dev/null +++ b/src/Orchard/Utility/DependencyOrderingUtility.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Orchard.Utility { + public static class DependencyOrdering { + + class Linkage { + public T Element { get; set; } + public bool Used { get; set; } + } + + /// + /// Sort a collection of elements "by dependency order". By passing a lambda which determines if an element + /// is a dependency of another, this algorithm will return the collection of elements sorted + /// so that a given element in the sequence doesn't depend on any other element further in the sequence. + /// + public static IEnumerable OrderByDependencies(this IEnumerable elements, Func hasDependency) { + var population = elements.Select(d => new Linkage { + Element = d + }).ToArray(); + + var result = new List(); + foreach (var item in population) { + Add(item, result, population, hasDependency); + } + return result; + } + + private static void Add(Linkage item, ICollection list, IEnumerable> population, Func hasDependency) { + if (item.Used) + return; + + item.Used = true; + foreach (var dependency in population.Where(dep => hasDependency(item.Element, dep.Element))) { + Add(dependency, list, population, hasDependency); + } + list.Add(item.Element); + } + } +} \ No newline at end of file