mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Incremental change refactoring modularity
--HG-- branch : dev
This commit is contained in:
@@ -1,29 +1,133 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Extensions;
|
||||
using Orchard.Tests.ContentManagement.Records;
|
||||
using Orchard.Tests.ContentManagement.Models;
|
||||
using Orchard.Extensions.Models;
|
||||
using Orchard.Tests.Utility;
|
||||
|
||||
namespace Orchard.Tests.Environment {
|
||||
[TestFixture]
|
||||
public class DefaultCompositionStrategyTests {
|
||||
[Test]
|
||||
public void ExpectedRecordsShouldComeBack() {
|
||||
var extensionManager = new Moq.Mock<IExtensionManager>();
|
||||
extensionManager.Setup(x => x.ActiveExtensions()).Returns(new[] {
|
||||
new ExtensionEntry {
|
||||
Descriptor = new ExtensionDescriptor { Name = "Test" },
|
||||
ExportedTypes = new[] { typeof(GammaRecord), typeof(DeltaRecord), typeof(Delta) }
|
||||
}
|
||||
});
|
||||
var strategy = new DefaultCompositionStrategy(extensionManager.Object);
|
||||
var recordTypes = strategy.GetRecordDescriptors().Select(d => d.Type);
|
||||
|
||||
Assert.That(recordTypes.Count(), Is.Not.EqualTo(0));
|
||||
Assert.That(recordTypes, Has.Some.EqualTo(typeof(DeltaRecord)));
|
||||
Assert.That(recordTypes, Has.Some.EqualTo(typeof(GammaRecord)));
|
||||
Assert.That(recordTypes, Has.None.EqualTo(typeof(Delta)));
|
||||
private IContainer _container;
|
||||
|
||||
private IEnumerable<ExtensionDescriptor> _extensionDescriptors;
|
||||
private IDictionary<string, IEnumerable<Type>> _featureTypes;
|
||||
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<DefaultCompositionStrategy>().As<ICompositionStrategy>();
|
||||
builder.RegisterAutoMocking(MockBehavior.Strict);
|
||||
_container = builder.Build();
|
||||
|
||||
_extensionDescriptors = Enumerable.Empty<ExtensionDescriptor>();
|
||||
_featureTypes = new Dictionary<string, IEnumerable<Type>>();
|
||||
|
||||
_container.Mock<IExtensionManager>()
|
||||
.Setup(x => x.AvailableExtensions())
|
||||
.Returns(() => _extensionDescriptors);
|
||||
|
||||
_container.Mock<IExtensionManager>()
|
||||
.Setup(x => x.LoadFeatures(It.IsAny<IEnumerable<FeatureDescriptor>>()))
|
||||
.Returns((IEnumerable<FeatureDescriptor> x) => StubLoadFeatures(x));
|
||||
}
|
||||
|
||||
private IEnumerable<Feature> StubLoadFeatures(IEnumerable<FeatureDescriptor> featureDescriptors) {
|
||||
return featureDescriptors.Select(featureDescriptor => new Feature {
|
||||
FeatureDescriptor = featureDescriptor,
|
||||
ExportedTypes = _featureTypes[featureDescriptor.Name]
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TopologyIsNotNull() {
|
||||
var descriptor = Build.TopologyDescriptor();
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(descriptor);
|
||||
|
||||
Assert.That(topology, Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DependenciesFromFeatureArePutIntoTopology() {
|
||||
var descriptor = Build.TopologyDescriptor().WithFeatures("Foo", "Bar");
|
||||
|
||||
_extensionDescriptors = new[] {
|
||||
Build.ExtensionDescriptor("Foo").WithFeatures("Foo"),
|
||||
Build.ExtensionDescriptor("Bar").WithFeatures("Bar"),
|
||||
};
|
||||
|
||||
_featureTypes["Foo"] = new[] { typeof(FooService1) };
|
||||
_featureTypes["Bar"] = new[] { typeof(BarService1) };
|
||||
|
||||
var compositionStrategy = _container.Resolve<ICompositionStrategy>();
|
||||
var topology = compositionStrategy.Compose(descriptor);
|
||||
|
||||
Assert.That(topology, Is.Not.Null);
|
||||
Assert.That(topology.Dependencies.Count(), Is.EqualTo(2));
|
||||
|
||||
var foo = topology.Dependencies.SingleOrDefault(t => t.Type == typeof (FooService1));
|
||||
Assert.That(foo, Is.Not.Null);
|
||||
Assert.That(foo.Feature.FeatureDescriptor.Name, Is.EqualTo("Foo"));
|
||||
|
||||
var bar = topology.Dependencies.SingleOrDefault(t => t.Type == typeof(BarService1));
|
||||
Assert.That(bar, Is.Not.Null);
|
||||
Assert.That(bar.Feature.FeatureDescriptor.Name, Is.EqualTo("Bar"));
|
||||
}
|
||||
|
||||
public interface IFooService : IDependency {
|
||||
}
|
||||
|
||||
public class FooService1 : IFooService {
|
||||
}
|
||||
|
||||
public interface IBarService : IDependency {
|
||||
}
|
||||
|
||||
public class BarService1 : IBarService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class Build {
|
||||
|
||||
public static ShellTopologyDescriptor TopologyDescriptor() {
|
||||
var descriptor = new ShellTopologyDescriptor {
|
||||
EnabledFeatures = Enumerable.Empty<TopologyFeature>(),
|
||||
};
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public static ShellTopologyDescriptor WithFeatures(this ShellTopologyDescriptor descriptor, params string[] names) {
|
||||
descriptor.EnabledFeatures = descriptor.EnabledFeatures.Concat(
|
||||
names.Select(name => new TopologyFeature { Name = name }));
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public static ExtensionDescriptor ExtensionDescriptor(string name) {
|
||||
var descriptor = new ExtensionDescriptor {
|
||||
Name = name,
|
||||
DisplayName = name,
|
||||
Features = Enumerable.Empty<FeatureDescriptor>(),
|
||||
};
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public static ExtensionDescriptor WithFeatures(this ExtensionDescriptor descriptor, params string[] names) {
|
||||
descriptor.Features = descriptor.Features.Concat(
|
||||
names.Select(name => new FeatureDescriptor() { Name = name }));
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Extensions.Models;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Mvc.ModelBinders;
|
||||
using Orchard.Mvc.Routes;
|
||||
@@ -78,6 +79,10 @@ namespace Orchard.Tests.Environment {
|
||||
return Enumerable.Empty<ExtensionDescriptor>();
|
||||
}
|
||||
|
||||
public IEnumerable<Feature> LoadFeatures(IEnumerable<FeatureDescriptor> features) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<ExtensionEntry> ActiveExtensions() {
|
||||
return Enumerable.Empty<ExtensionEntry>();
|
||||
}
|
||||
|
@@ -1,17 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Autofac;
|
||||
using Autofac.Builder;
|
||||
using Autofac.Core;
|
||||
using Autofac;
|
||||
using Autofac.Core.Registration;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Tests.Utility;
|
||||
|
||||
namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
[TestFixture]
|
||||
@@ -22,7 +17,7 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<DefaultShellContextFactory>().As<IShellContextFactory>();
|
||||
builder.RegisterSource(new MockServiceSource());
|
||||
builder.RegisterAutoMocking();
|
||||
_container = builder.Build();
|
||||
}
|
||||
|
||||
@@ -60,39 +55,4 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
Assert.That(context.Shell, Is.SameAs(shellLifetimeScope.Resolve<IOrchardShell>()));
|
||||
}
|
||||
}
|
||||
|
||||
class MockServiceSource : IRegistrationSource {
|
||||
public IEnumerable<IComponentRegistration> RegistrationsFor(
|
||||
Service service,
|
||||
Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor) {
|
||||
|
||||
var swt = service as IServiceWithType;
|
||||
if (swt == null)
|
||||
yield break;
|
||||
var st = swt.ServiceType;
|
||||
|
||||
if (st.IsGenericType && st.GetGenericTypeDefinition() == typeof(Mock<>)) {
|
||||
yield return RegistrationBuilder.ForType(st).SingleInstance().CreateRegistration();
|
||||
}
|
||||
else if (st.IsInterface) {
|
||||
yield return RegistrationBuilder.ForDelegate(
|
||||
(ctx, p) => {
|
||||
Trace.WriteLine(string.Format("Mocking {0}", st));
|
||||
var mt = typeof(Mock<>).MakeGenericType(st);
|
||||
var m = (Mock)ctx.Resolve(mt);
|
||||
return m.Object;
|
||||
})
|
||||
.As(service)
|
||||
.SingleInstance()
|
||||
.CreateRegistration();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MockExtensions {
|
||||
public static Mock<T> Mock<T>(this IContainer container) where T : class {
|
||||
return container.Resolve<Mock<T>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ using Autofac;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Extensions;
|
||||
using Orchard.Extensions.Loaders;
|
||||
using Orchard.Extensions.Models;
|
||||
using Orchard.Tests.Extensions.ExtensionTypes;
|
||||
using Yaml.Grammar;
|
||||
|
||||
|
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Extensions.Models;
|
||||
using Orchard.Mvc.Routes;
|
||||
using Orchard.Extensions;
|
||||
|
||||
@@ -39,6 +40,10 @@ namespace Orchard.Tests.Mvc.Routes {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<Feature> LoadFeatures(IEnumerable<FeatureDescriptor> features) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<ExtensionEntry> ActiveExtensions() {
|
||||
yield return new ExtensionEntry {
|
||||
Descriptor = new ExtensionDescriptor {
|
||||
|
@@ -165,6 +165,7 @@
|
||||
<Compile Include="Environment\OrchardStarterTests.cs" />
|
||||
<Compile Include="Environment\ShellBuilders\DefaultShellContainerFactoryTests.cs" />
|
||||
<Compile Include="Environment\ShellBuilders\DefaultShellContextFactoryTests.cs" />
|
||||
<Compile Include="Utility\ContainerExtensions.cs" />
|
||||
<Compile Include="Environment\ShellBuilders\SetupShellContainerFactoryTests.cs" />
|
||||
<Compile Include="Environment\TestDependencies\TestDependency.cs" />
|
||||
<Compile Include="Environment\Topology\DefaultTopologyDescriptorCacheTests.cs" />
|
||||
|
61
src/Orchard.Tests/Utility/ContainerExtensions.cs
Normal file
61
src/Orchard.Tests/Utility/ContainerExtensions.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Autofac;
|
||||
using Autofac.Builder;
|
||||
using Autofac.Core;
|
||||
using Moq;
|
||||
|
||||
namespace Orchard.Tests.Utility {
|
||||
public static class ContainerExtensions {
|
||||
public static Mock<T> Mock<T>(this IContainer container) where T : class {
|
||||
return container.Resolve<Mock<T>>();
|
||||
}
|
||||
|
||||
public static void RegisterAutoMocking(this ContainerBuilder builder) {
|
||||
builder.RegisterSource(new AutoMockSource(MockBehavior.Default));
|
||||
}
|
||||
|
||||
public static void RegisterAutoMocking(this ContainerBuilder builder, MockBehavior behavior) {
|
||||
builder.RegisterSource(new AutoMockSource(behavior));
|
||||
}
|
||||
class AutoMockSource : IRegistrationSource {
|
||||
private readonly MockBehavior _behavior;
|
||||
|
||||
public AutoMockSource(MockBehavior behavior) {
|
||||
_behavior = behavior;
|
||||
}
|
||||
|
||||
public IEnumerable<IComponentRegistration> RegistrationsFor(
|
||||
Service service,
|
||||
Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor) {
|
||||
|
||||
var swt = service as IServiceWithType;
|
||||
if (swt == null)
|
||||
yield break;
|
||||
var st = swt.ServiceType;
|
||||
|
||||
if (st.IsGenericType && st.GetGenericTypeDefinition() == typeof(Mock<>)) {
|
||||
yield return RegistrationBuilder.ForType(st)
|
||||
.SingleInstance()
|
||||
.WithParameter("behavior", _behavior)
|
||||
.CreateRegistration();
|
||||
}
|
||||
else if (st.IsInterface) {
|
||||
yield return RegistrationBuilder.ForDelegate(
|
||||
(ctx, p) => {
|
||||
Trace.WriteLine(string.Format("Mocking {0}", st));
|
||||
var mt = typeof(Mock<>).MakeGenericType(st);
|
||||
var m = (Mock)ctx.Resolve(mt);
|
||||
return m.Object;
|
||||
})
|
||||
.As(service)
|
||||
.SingleInstance()
|
||||
.CreateRegistration();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -2,10 +2,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Web.Mvc;
|
||||
using Autofac.Core;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Extensions;
|
||||
using Orchard.Extensions.Models;
|
||||
using Orchard.Utility.Extensions;
|
||||
using Orchard.Extensions.Records;
|
||||
|
||||
@@ -23,13 +27,83 @@ namespace Orchard.Environment {
|
||||
public string Prefix { get; set; }
|
||||
}
|
||||
|
||||
public class DefaultCompositionStrategy : ICompositionStrategy_Obsolete {
|
||||
public class DefaultCompositionStrategy : ICompositionStrategy, ICompositionStrategy_Obsolete {
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
|
||||
public DefaultCompositionStrategy(IExtensionManager extensionManager) {
|
||||
_extensionManager = extensionManager;
|
||||
}
|
||||
|
||||
public ShellTopology Compose(ShellTopologyDescriptor topologyDescriptor) {
|
||||
|
||||
var featureDescriptors = _extensionManager.AvailableExtensions()
|
||||
.SelectMany(extensionDescriptor => extensionDescriptor.Features)
|
||||
.Where(featureDescriptor => IsFeatureEnabledInTopology(featureDescriptor, topologyDescriptor));
|
||||
|
||||
var features = _extensionManager.LoadFeatures(featureDescriptors);
|
||||
|
||||
return new ShellTopology {
|
||||
Modules = BuildTopology<ModuleTopology>(features, IsModule, BuildModule),
|
||||
Dependencies = BuildTopology<DependencyTopology>(features, IsDependency, BuildDependency),
|
||||
Controllers = BuildTopology<ControllerTopology>(features, IsController, BuildController),
|
||||
Records = BuildTopology<RecordTopology>(features, IsRecord, BuildRecord),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static bool IsFeatureEnabledInTopology(FeatureDescriptor featureDescriptor, ShellTopologyDescriptor topologyDescriptor) {
|
||||
return topologyDescriptor.EnabledFeatures.Any(topologyFeature => topologyFeature.Name == featureDescriptor.Name);
|
||||
}
|
||||
|
||||
private static IEnumerable<T> BuildTopology<T>(
|
||||
IEnumerable<Feature> features,
|
||||
Func<Type, bool> predicate,
|
||||
Func<Type, Feature, T> selector) {
|
||||
return features.SelectMany(
|
||||
feature => feature.ExportedTypes
|
||||
.Where(predicate)
|
||||
.Select(type => selector(type, feature)))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static bool IsModule(Type type) {
|
||||
return typeof(IModule).IsAssignableFrom(type);
|
||||
}
|
||||
|
||||
private static ModuleTopology BuildModule(Type type, Feature feature) {
|
||||
return new ModuleTopology { Type = type, Feature = feature };
|
||||
}
|
||||
|
||||
private static bool IsDependency(Type type) {
|
||||
return typeof(IDependency).IsAssignableFrom(type);
|
||||
}
|
||||
|
||||
private static DependencyTopology BuildDependency(Type type, Feature feature) {
|
||||
return new DependencyTopology {Type = type, Feature = feature};
|
||||
}
|
||||
|
||||
private static bool IsController(Type type) {
|
||||
return typeof(IController).IsAssignableFrom(type);
|
||||
}
|
||||
|
||||
private static ControllerTopology BuildController(Type type, Feature feature) {
|
||||
return new ControllerTopology { Type = type, Feature = feature };
|
||||
}
|
||||
|
||||
private static bool IsRecord(Type type) {
|
||||
return ((type.Namespace ?? "").EndsWith(".Models") || (type.Namespace ?? "").EndsWith(".Records")) &&
|
||||
type.GetProperty("Id") != null &&
|
||||
(type.GetProperty("Id").GetAccessors() ?? Enumerable.Empty<MethodInfo>()).All(x => x.IsVirtual) &&
|
||||
!type.IsSealed &&
|
||||
!type.IsAbstract &&
|
||||
(!typeof(IContent).IsAssignableFrom(type) || typeof(ContentPartRecord).IsAssignableFrom(type));;
|
||||
}
|
||||
|
||||
private static RecordTopology BuildRecord(Type type, Feature feature) {
|
||||
return new RecordTopology { Type = type, Feature = feature };
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<Type> GetModuleTypes() {
|
||||
return _extensionManager.GetExtensionsTopology().Types.Where(t => typeof(IModule).IsAssignableFrom(t));
|
||||
}
|
||||
@@ -70,5 +144,6 @@ namespace Orchard.Environment {
|
||||
!type.IsAbstract &&
|
||||
(!typeof(IContent).IsAssignableFrom(type) || typeof(ContentPartRecord).IsAssignableFrom(type));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -2,10 +2,10 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Extensions.Models;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Mvc.ModelBinders;
|
||||
using Orchard.Mvc.Routes;
|
||||
using Orchard.Extensions;
|
||||
using Orchard.Utility;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Extensions;
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Environment.Topology.Models {
|
||||
public class ShellTopology {
|
||||
@@ -14,6 +15,7 @@ namespace Orchard.Environment.Topology.Models {
|
||||
|
||||
public class ShellTopologyItem {
|
||||
public Type Type { get; set; }
|
||||
public Feature Feature { get; set; }
|
||||
public ExtensionDescriptor ExtensionDescriptor { get; set; }
|
||||
public FeatureDescriptor FeatureDescriptor { get; set; }
|
||||
public ExtensionEntry ExtensionEntry { get; set; }
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Extensions {
|
||||
public class ExtensionEntry {
|
||||
|
@@ -6,6 +6,7 @@ using ICSharpCode.SharpZipLib.Zip;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Extensions.Helpers;
|
||||
using Orchard.Extensions.Loaders;
|
||||
using Orchard.Extensions.Models;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Yaml.Grammar;
|
||||
@@ -45,6 +46,10 @@ namespace Orchard.Extensions {
|
||||
return availableExtensions;
|
||||
}
|
||||
|
||||
public IEnumerable<Feature> LoadFeatures(IEnumerable<FeatureDescriptor> features) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
// This method loads types from extensions into the ExtensionEntry array.
|
||||
public IEnumerable<ExtensionEntry> ActiveExtensions() {
|
||||
if (_activeExtensions == null) {
|
||||
@@ -52,6 +57,7 @@ namespace Orchard.Extensions {
|
||||
}
|
||||
return _activeExtensions;
|
||||
}
|
||||
|
||||
|
||||
private static ExtensionDescriptor GetDescriptorForExtension(string name, IExtensionFolders folder) {
|
||||
string extensionType = folder is ThemeFolders ? "Theme" : "Module";
|
||||
|
@@ -1,13 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Extensions {
|
||||
public interface IExtensionManager {
|
||||
IEnumerable<ExtensionDescriptor> AvailableExtensions();
|
||||
IEnumerable<Type> LoadFeature(string featureName);
|
||||
IEnumerable<Feature> LoadFeatures(IEnumerable<FeatureDescriptor> features);
|
||||
|
||||
IEnumerable<ExtensionEntry> ActiveExtensions();
|
||||
ShellTopology_Obsolete GetExtensionsTopology();
|
||||
IEnumerable<Type> LoadFeature(string featureName);
|
||||
|
||||
void InstallExtension(string extensionType, HttpPostedFileBase extensionBundle);
|
||||
void UninstallExtension(string extensionType, string extensionName);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Extensions.Loaders {
|
||||
public class AreaExtensionLoader : IExtensionLoader {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Extensions.Loaders {
|
||||
public class CoreExtensionLoader : IExtensionLoader {
|
||||
|
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.Hosting;
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Extensions.Loaders {
|
||||
public class DynamicExtensionLoader : IExtensionLoader {
|
||||
|
@@ -1,4 +1,6 @@
|
||||
namespace Orchard.Extensions.Loaders {
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Extensions.Loaders {
|
||||
public interface IExtensionLoader {
|
||||
int Order { get; }
|
||||
ExtensionEntry Load(ExtensionDescriptor descriptor);
|
||||
|
@@ -1,4 +1,6 @@
|
||||
namespace Orchard.Extensions.Loaders {
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Extensions.Loaders {
|
||||
public class PrecompiledExtensionLoader : IExtensionLoader {
|
||||
public int Order { get { return 3; } }
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using System.Reflection;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.Hosting;
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Extensions.Loaders {
|
||||
public class ReferencedExtensionLoader : IExtensionLoader {
|
||||
|
4
src/Orchard/Extensions/Models/Extension.cs
Normal file
4
src/Orchard/Extensions/Models/Extension.cs
Normal file
@@ -0,0 +1,4 @@
|
||||
namespace Orchard.Extensions.Models {
|
||||
public class Extension {
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.Extensions {
|
||||
namespace Orchard.Extensions.Models {
|
||||
public class ExtensionDescriptor {
|
||||
/// <summary>
|
||||
/// Virtual path base, "~/Themes", "~/Modules", or "~/Core"
|
||||
@@ -29,4 +29,4 @@ namespace Orchard.Extensions {
|
||||
|
||||
public IEnumerable<FeatureDescriptor> Features { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
10
src/Orchard/Extensions/Models/Feature.cs
Normal file
10
src/Orchard/Extensions/Models/Feature.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.Extensions.Models {
|
||||
public class Feature {
|
||||
public FeatureDescriptor FeatureDescriptor { get; set; }
|
||||
public Extension Extension { get; set; }
|
||||
public IEnumerable<Type> ExportedTypes { get; set; }
|
||||
}
|
||||
}
|
@@ -189,8 +189,10 @@
|
||||
<Compile Include="Events\IEventBusHandler.cs" />
|
||||
<Compile Include="Extensions\AreaFolders.cs" />
|
||||
<Compile Include="Extensions\ExtensionFolders.cs" />
|
||||
<Compile Include="Extensions\FeatureDescriptor.cs" />
|
||||
<Compile Include="Extensions\Models\Extension.cs" />
|
||||
<Compile Include="Extensions\Models\FeatureDescriptor.cs" />
|
||||
<Compile Include="Extensions\Loaders\AreaExtensionLoader.cs" />
|
||||
<Compile Include="Extensions\Models\Feature.cs" />
|
||||
<Compile Include="Extensions\OrchardFeatureAttribute.cs" />
|
||||
<Compile Include="Extensions\Records\ExtensionRecord.cs" />
|
||||
<Compile Include="Extensions\ShellTopology.cs" />
|
||||
@@ -271,7 +273,7 @@
|
||||
<Compile Include="Data\TransactionManager.cs" />
|
||||
<Compile Include="Environment\IOrchardShellEvents.cs" />
|
||||
<Compile Include="Environment\OrchardServices.cs" />
|
||||
<Compile Include="Extensions\ExtensionDescriptor.cs" />
|
||||
<Compile Include="Extensions\Models\ExtensionDescriptor.cs" />
|
||||
<Compile Include="Extensions\ExtensionEntry.cs" />
|
||||
<Compile Include="IOrchardServices.cs" />
|
||||
<Compile Include="Themes\ThemeFilter.cs" />
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Orchard.Extensions;
|
||||
using Orchard.Extensions.Models;
|
||||
|
||||
namespace Orchard.Themes {
|
||||
public static class ExtensionManagerExtensions {
|
||||
|
Reference in New Issue
Block a user