Generalize the dependy ordering algorithm

--HG--
branch : dev
This commit is contained in:
Renaud Paquay
2010-06-30 23:39:38 -07:00
parent 65c3ff3cd7
commit 5b89b6a78d
3 changed files with 45 additions and 32 deletions

View File

@@ -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<FeatureDescriptor> OrderByDependencies(IEnumerable<FeatureDescriptor> descriptors) {
var population = descriptors.Select(d => new Linkage {
Feature = d
}).ToArray();
var result = new List<FeatureDescriptor>();
foreach (var item in population) {
Add(item, result, population);
}
return result;
}
private static void Add(Linkage item, ICollection<FeatureDescriptor> list, IEnumerable<Linkage> population) {
if (item.Used)
return;
item.Used = true;
var dependencies = item.Feature.Dependencies ?? Enumerable.Empty<string>();
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)));
}
}
}

View File

@@ -402,6 +402,7 @@
<Compile Include="Environment\Extensions\Compilers\CSharpExtensionBuildProviderShim.cs" />
<Compile Include="Environment\Extensions\Compilers\ProjectFileDescriptor.cs" />
<Compile Include="Environment\Extensions\Compilers\IProjectFileParser.cs" />
<Compile Include="Utility\DependencyOrderingUtility.cs" />
<Compile Include="Environment\IOrchardHostContainer.cs" />
<Compile Include="Environment\IShim.cs" />
<Compile Include="Environment\OrchardHostContainerRegistry.cs" />

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Orchard.Utility {
public static class DependencyOrdering {
class Linkage<T> {
public T Element { get; set; }
public bool Used { get; set; }
}
/// <summary>
/// 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.
/// </summary>
public static IEnumerable<T> OrderByDependencies<T>(this IEnumerable<T> elements, Func<T, T, bool> hasDependency) {
var population = elements.Select(d => new Linkage<T> {
Element = d
}).ToArray();
var result = new List<T>();
foreach (var item in population) {
Add(item, result, population, hasDependency);
}
return result;
}
private static void Add<T>(Linkage<T> item, ICollection<T> list, IEnumerable<Linkage<T>> population, Func<T, T, bool> 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);
}
}
}