mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Generalize the dependy ordering algorithm
--HG-- branch : dev
This commit is contained in:
@@ -7,6 +7,7 @@ using Orchard.Environment.Extensions.Models;
|
|||||||
using Orchard.Environment.State.Models;
|
using Orchard.Environment.State.Models;
|
||||||
using Orchard.Environment.Descriptor;
|
using Orchard.Environment.Descriptor;
|
||||||
using Orchard.Environment.Descriptor.Models;
|
using Orchard.Environment.Descriptor.Models;
|
||||||
|
using Orchard.Utility;
|
||||||
|
|
||||||
namespace Orchard.Environment.State {
|
namespace Orchard.Environment.State {
|
||||||
public class ShellStateCoordinator : IShellStateManagerEventHandler, IShellDescriptorManagerEventHandler {
|
public class ShellStateCoordinator : IShellStateManagerEventHandler, IShellDescriptorManagerEventHandler {
|
||||||
@@ -184,39 +185,9 @@ namespace Orchard.Environment.State {
|
|||||||
state.EnableState == ShellFeatureState.State.Rising;
|
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) {
|
public static IEnumerable<FeatureDescriptor> OrderByDependencies(IEnumerable<FeatureDescriptor> descriptors) {
|
||||||
var population = descriptors.Select(d => new Linkage {
|
return descriptors.OrderByDependencies((item, dep) =>
|
||||||
Feature = d
|
item.Dependencies.Any(x => StringComparer.OrdinalIgnoreCase.Equals(x, dep.Name)));
|
||||||
}).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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -402,6 +402,7 @@
|
|||||||
<Compile Include="Environment\Extensions\Compilers\CSharpExtensionBuildProviderShim.cs" />
|
<Compile Include="Environment\Extensions\Compilers\CSharpExtensionBuildProviderShim.cs" />
|
||||||
<Compile Include="Environment\Extensions\Compilers\ProjectFileDescriptor.cs" />
|
<Compile Include="Environment\Extensions\Compilers\ProjectFileDescriptor.cs" />
|
||||||
<Compile Include="Environment\Extensions\Compilers\IProjectFileParser.cs" />
|
<Compile Include="Environment\Extensions\Compilers\IProjectFileParser.cs" />
|
||||||
|
<Compile Include="Utility\DependencyOrderingUtility.cs" />
|
||||||
<Compile Include="Environment\IOrchardHostContainer.cs" />
|
<Compile Include="Environment\IOrchardHostContainer.cs" />
|
||||||
<Compile Include="Environment\IShim.cs" />
|
<Compile Include="Environment\IShim.cs" />
|
||||||
<Compile Include="Environment\OrchardHostContainerRegistry.cs" />
|
<Compile Include="Environment\OrchardHostContainerRegistry.cs" />
|
||||||
|
|||||||
41
src/Orchard/Utility/DependencyOrderingUtility.cs
Normal file
41
src/Orchard/Utility/DependencyOrderingUtility.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user