mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 10:54:50 +08:00
Working towards re-enabling setup context
--HG-- branch : dev
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -15,13 +16,29 @@ namespace Orchard.Specs.Bindings {
|
||||
public class WebAppHosting {
|
||||
private WebHost _webHost;
|
||||
private RequestDetails _details;
|
||||
private MessageSink _messages;
|
||||
|
||||
[Given(@"I have a clean site")]
|
||||
public void GivenIHaveACleanSite() {
|
||||
_webHost = new WebHost();
|
||||
_webHost.Initialize("Orchard.Web", "/");
|
||||
|
||||
var sink = new MessageSink();
|
||||
_webHost.Execute(() => {
|
||||
HostingTraceListener.SetHook(msg => sink.Receive(msg));
|
||||
});
|
||||
_messages = sink;
|
||||
}
|
||||
|
||||
public class MessageSink : MarshalByRefObject {
|
||||
readonly IList<string> _messages = new List<string>();
|
||||
|
||||
public void Receive(string message) {
|
||||
_messages.Add(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Given(@"I have module ""(.*)""")]
|
||||
public void GivenIHaveModule(string moduleName) {
|
||||
_webHost.CopyExtension("Modules", moduleName);
|
||||
|
24
src/Orchard.Specs/Hosting/HostingTraceListener.cs
Normal file
24
src/Orchard.Specs/Hosting/HostingTraceListener.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Orchard.Specs.Hosting {
|
||||
public class HostingTraceListener : TraceListener {
|
||||
private static Action<string> _hook = ignored => { };
|
||||
private string _message;
|
||||
|
||||
public static void SetHook(Action<string> hook) {
|
||||
_hook = hook;
|
||||
}
|
||||
|
||||
public override void Write(string message) {
|
||||
var cumulative = _message + message;
|
||||
_message = cumulative;
|
||||
}
|
||||
|
||||
public override void WriteLine(string message) {
|
||||
var cumulative = _message + message;
|
||||
_message = null;
|
||||
_hook(cumulative);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
<system.diagnostics>
|
||||
<trace autoflush="true"/>
|
||||
<sources>
|
||||
<source name="Default" switchValue="Verbose">
|
||||
<listeners>
|
||||
<add name="CaptureTraceMessages" />
|
||||
</listeners>
|
||||
</source>
|
||||
</sources>
|
||||
<sharedListeners>
|
||||
<add name="CaptureTraceMessages" type="Orchard.Specs.Hosting.HostingTraceListener, Orchard.Specs" initializeData="" />
|
||||
</sharedListeners>
|
||||
</system.diagnostics>
|
@@ -25,7 +25,7 @@
|
||||
|
||||
<appSettings/>
|
||||
|
||||
<!--<system.diagnostics configSource="Config\Diagnostics.config" />-->
|
||||
<system.diagnostics configSource="Config\Diagnostics.config" />
|
||||
|
||||
<!--
|
||||
Set default transaction timeout to 30 minutes so that interactive debugging
|
||||
|
@@ -33,6 +33,7 @@ namespace Orchard.Specs.Hosting {
|
||||
VirtualDirectory = virtualDirectory;
|
||||
|
||||
_webHostAgent = (WebHostAgent)ApplicationHost.CreateApplicationHost(typeof(WebHostAgent), VirtualDirectory, PhysicalDirectory);
|
||||
|
||||
}
|
||||
|
||||
public void CopyExtension(string extensionFolder, string extensionName) {
|
||||
|
@@ -86,6 +86,7 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Hosting\HostingTraceListener.cs" />
|
||||
<Compile Include="Hosting\Orchard.Web\HelloYetAgainHandler.cs" />
|
||||
<Compile Include="Hosting\RequestExtensions.cs" />
|
||||
<Compile Include="Hosting\RequestDetails.cs" />
|
||||
@@ -126,6 +127,9 @@
|
||||
<Content Include="Hosting\Orchard.Web\Themes\Web.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="Hosting\Orchard.Web\Config\Diagnostics.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="WebHosting.feature">
|
||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||
<LastGenOutput>WebHosting.feature.cs</LastGenOutput>
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using Autofac;
|
||||
using Autofac.Core.Registration;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
@@ -17,16 +18,16 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<DefaultShellContextFactory>().As<IShellContextFactory>();
|
||||
builder.RegisterAutoMocking();
|
||||
builder.RegisterAutoMocking(Moq.MockBehavior.Strict);
|
||||
_container = builder.Build();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NormalExecutionReturnsExpectedObjects() {
|
||||
var settings = new ShellSettings {Name = "Default"};
|
||||
var topologyDescriptor = new ShellTopologyDescriptor {SerialNumber = 6655321};
|
||||
var settings = new ShellSettings { Name = "Default" };
|
||||
var topologyDescriptor = new ShellTopologyDescriptor { SerialNumber = 6655321 };
|
||||
var topology = new ShellTopology();
|
||||
ILifetimeScope shellLifetimeScope;
|
||||
var shellLifetimeScope = _container.BeginLifetimeScope("shell");
|
||||
|
||||
_container.Mock<ITopologyDescriptorCache>()
|
||||
.Setup(x => x.Fetch("Default"))
|
||||
@@ -38,7 +39,7 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
|
||||
_container.Mock<IShellContainerFactory>()
|
||||
.Setup(x => x.CreateContainer(topology))
|
||||
.Returns(shellLifetimeScope = _container.BeginLifetimeScope("shell"));
|
||||
.Returns(shellLifetimeScope );
|
||||
|
||||
_container.Mock<ITopologyDescriptorManager>()
|
||||
.Setup(x => x.GetTopologyDescriptor())
|
||||
@@ -54,5 +55,23 @@ namespace Orchard.Tests.Environment.ShellBuilders {
|
||||
Assert.That(context.LifetimeScope, Is.SameAs(shellLifetimeScope));
|
||||
Assert.That(context.Shell, Is.SameAs(shellLifetimeScope.Resolve<IOrchardShell>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NullSettingsReturnsSetupContext() {
|
||||
var topology = new ShellTopology();
|
||||
|
||||
_container.Mock<ICompositionStrategy>()
|
||||
.Setup(x => x.Compose(It.IsAny<ShellTopologyDescriptor>()))
|
||||
.Returns(topology);
|
||||
|
||||
_container.Mock<IShellContainerFactory>()
|
||||
.Setup(x => x.CreateContainer(topology))
|
||||
.Returns(_container.BeginLifetimeScope("shell"));
|
||||
|
||||
var factory = _container.Resolve<IShellContextFactory>();
|
||||
var context = factory.Create(null);
|
||||
|
||||
Assert.That(context.TopologyDescriptor.EnabledFeatures, Has.Some.With.Property("Name").EqualTo("Setup"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,2 +1,5 @@
|
||||
name: Setup
|
||||
antiforgery: enabled
|
||||
antiforgery: enabled
|
||||
features:
|
||||
Orchard.Setup:
|
||||
description: Components needed to initialize a new instance or tenant
|
||||
|
@@ -47,6 +47,8 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
private static IEnumerable<Feature> CoreFeatures() {
|
||||
var frameworkTypes = typeof(OrchardStarter).Assembly.GetExportedTypes();
|
||||
|
||||
var core = new Feature {
|
||||
Descriptor = new FeatureDescriptor {
|
||||
Name = "Core",
|
||||
@@ -56,11 +58,12 @@ namespace Orchard.Environment {
|
||||
AntiForgery = "enabled",
|
||||
},
|
||||
},
|
||||
ExportedTypes = new[] {
|
||||
typeof (ContentTypeRecord),
|
||||
typeof (ContentItemRecord),
|
||||
typeof (ContentItemVersionRecord),
|
||||
},
|
||||
ExportedTypes = frameworkTypes.Where(t => t.IsClass && !t.IsAbstract),
|
||||
//ExportedTypes = new[] {
|
||||
// typeof (ContentTypeRecord),
|
||||
// typeof (ContentItemRecord),
|
||||
// typeof (ContentItemVersionRecord),
|
||||
//},
|
||||
};
|
||||
return new[] { core };
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Mvc.ViewEngines;
|
||||
using Orchard.Utility.Extensions;
|
||||
@@ -29,13 +30,17 @@ namespace Orchard.Environment {
|
||||
_tenantManager = tenantManager;
|
||||
_shellContextFactory = shellContextFactory;
|
||||
_controllerBuilder = controllerBuilder;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public IList<ShellContext> Current {
|
||||
get { return BuildCurrent().ToReadOnlyCollection(); }
|
||||
}
|
||||
|
||||
void IOrchardHost.Initialize() {
|
||||
Logger.Information("Initializing");
|
||||
ViewEngines.Engines.Insert(0, LayoutViewEngine.CreateShim());
|
||||
_controllerBuilder.SetControllerFactory(new OrchardControllerFactory());
|
||||
ServiceLocator.SetLocator(t => _containerProvider.RequestLifetime.Resolve(t));
|
||||
@@ -57,26 +62,40 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
IStandaloneEnvironment IOrchardHost.CreateStandaloneEnvironment(ShellSettings shellSettings) {
|
||||
var shellContext = _shellContextFactory.Create(shellSettings);
|
||||
Logger.Debug("Creating standalone environment for tenant {0}", shellSettings.Name);
|
||||
var shellContext = CreateShellContext(shellSettings);
|
||||
return new StandaloneEnvironment(shellContext.LifetimeScope);
|
||||
}
|
||||
|
||||
IEnumerable<ShellContext> GetCurrent() {
|
||||
lock (this) {
|
||||
return _current ?? (_current = BuildCurrent());
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<ShellContext> BuildCurrent() {
|
||||
return CreateAndActivate().ToArray();
|
||||
lock (this) {
|
||||
return _current ?? (_current = CreateAndActivate().ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<ShellContext> CreateAndActivate() {
|
||||
foreach(var settings in _tenantManager.LoadSettings()) {
|
||||
var context = _shellContextFactory.Create(settings);
|
||||
context.Shell.Activate();
|
||||
yield return context;
|
||||
var allSettings = _tenantManager.LoadSettings();
|
||||
if (allSettings.Any()) {
|
||||
return allSettings.Select(
|
||||
settings => {
|
||||
var context = CreateShellContext(settings);
|
||||
context.Shell.Activate();
|
||||
return context;
|
||||
});
|
||||
}
|
||||
|
||||
return new[] {CreateSetupContext()};
|
||||
}
|
||||
|
||||
ShellContext CreateSetupContext() {
|
||||
Logger.Debug("Creating shell context for setup");
|
||||
return _shellContextFactory.Create(null);
|
||||
}
|
||||
|
||||
ShellContext CreateShellContext(ShellSettings settings) {
|
||||
Logger.Debug("Creating shell context for tenant {0}", settings.Name);
|
||||
return _shellContextFactory.Create(settings);
|
||||
}
|
||||
|
||||
protected virtual void BeginRequest() {
|
||||
@@ -99,7 +118,7 @@ namespace Orchard.Environment {
|
||||
finally {
|
||||
containerProvider.EndRequestLifetime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +0,0 @@
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
public class HostContext {
|
||||
public ControllerBuilder ControllerBuilder { get; set; }
|
||||
public RouteCollection Routes { get; set; }
|
||||
}
|
||||
}
|
@@ -13,52 +13,71 @@ using Orchard.Environment.Extensions.Loaders;
|
||||
using Orchard.Environment.ShellBuilders;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Events;
|
||||
using Orchard.Logging;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
public static class OrchardStarter {
|
||||
public static IContainer CreateHostContainer(Action<ContainerBuilder> registrations) {
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterModule(new LoggingModule());
|
||||
|
||||
// a single default host implementation is needed for bootstrapping a web app domain
|
||||
builder.RegisterType<DefaultOrchardHost>().As<IOrchardHost>().SingleInstance();
|
||||
builder.RegisterType<DefaultCompositionStrategy>().As<ICompositionStrategy_Obsolete>().SingleInstance();
|
||||
builder.RegisterType<DefaultShellContainerFactory>().As<IShellContainerFactory>().SingleInstance();
|
||||
builder.RegisterType<AppDataFolder>().As<IAppDataFolder>().SingleInstance();
|
||||
builder.RegisterType<DefaultTenantManager>().As<ITenantManager>().SingleInstance();
|
||||
builder.RegisterType<SafeModeShellContainerFactory>().As<IShellContainerFactory_Obsolete>().SingleInstance();
|
||||
builder.RegisterType<DefaultTopologyDescriptorCache>().As<ITopologyDescriptorCache>().SingleInstance();
|
||||
|
||||
builder.RegisterType<DefaultOrchardEventBus>().As<IEventBus>().SingleInstance();
|
||||
builder.RegisterType<AppDataFolder>().As<IAppDataFolder>().SingleInstance();
|
||||
|
||||
builder.RegisterType<DefaultOrchardHost>().As<IOrchardHost>().SingleInstance();
|
||||
{
|
||||
builder.RegisterType<DefaultTenantManager>().As<ITenantManager>().SingleInstance();
|
||||
|
||||
builder.RegisterType<DefaultShellContextFactory>().As<IShellContextFactory>().SingleInstance();
|
||||
{
|
||||
builder.RegisterType<DefaultTopologyDescriptorCache>().As<ITopologyDescriptorCache>().SingleInstance();
|
||||
|
||||
builder.RegisterType<DefaultCompositionStrategy>()
|
||||
.As<ICompositionStrategy>()
|
||||
.As<ICompositionStrategy_Obsolete>()
|
||||
.SingleInstance();
|
||||
{
|
||||
builder.RegisterType<ExtensionManager>().As<IExtensionManager>().SingleInstance();
|
||||
{
|
||||
builder.RegisterType<ModuleFolders>().As<IExtensionFolders>()
|
||||
.WithParameter(new NamedParameter("paths", new[] { "~/Core", "~/Modules" }))
|
||||
.SingleInstance();
|
||||
builder.RegisterType<AreaFolders>().As<IExtensionFolders>()
|
||||
.WithParameter(new NamedParameter("paths", new[] { "~/Areas" }))
|
||||
.SingleInstance();
|
||||
builder.RegisterType<ThemeFolders>().As<IExtensionFolders>()
|
||||
.WithParameter(new NamedParameter("paths", new[] { "~/Core", "~/Themes" }))
|
||||
.SingleInstance();
|
||||
|
||||
builder.RegisterType<AreaExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
builder.RegisterType<CoreExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
builder.RegisterType<ReferencedExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
builder.RegisterType<PrecompiledExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
builder.RegisterType<DynamicExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
}
|
||||
}
|
||||
|
||||
builder.RegisterType<DefaultShellContainerFactory>().As<IShellContainerFactory>().SingleInstance();
|
||||
}
|
||||
}
|
||||
|
||||
builder.RegisterType<DefaultOrchardShell>().As<IOrchardShell>().InstancePerMatchingLifetimeScope("shell");
|
||||
|
||||
// The container provider gives you access to the lowest container at the time,
|
||||
// and dynamically creates a per-request container. The EndRequestLifetime method
|
||||
// still needs to be called on end request, but that's the host component's job to worry about
|
||||
builder.RegisterType<ContainerProvider>().As<IContainerProvider>().InstancePerLifetimeScope();
|
||||
|
||||
builder.RegisterType<ExtensionManager>().As<IExtensionManager>().SingleInstance();
|
||||
builder.RegisterType<AreaExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
builder.RegisterType<CoreExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
builder.RegisterType<ReferencedExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
builder.RegisterType<PrecompiledExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
builder.RegisterType<DynamicExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
|
||||
builder.RegisterType<ModuleFolders>().As<IExtensionFolders>()
|
||||
.WithParameter(new NamedParameter("paths", new[] { "~/Core", "~/Modules" }))
|
||||
.SingleInstance();
|
||||
builder.RegisterType<AreaFolders>().As<IExtensionFolders>()
|
||||
.WithParameter(new NamedParameter("paths", new[] { "~/Areas" }))
|
||||
.SingleInstance();
|
||||
builder.RegisterType<ThemeFolders>().As<IExtensionFolders>()
|
||||
.WithParameter(new NamedParameter("paths", new[] { "~/Core", "~/Themes" }))
|
||||
.SingleInstance();
|
||||
|
||||
registrations(builder);
|
||||
|
||||
|
||||
|
||||
var autofacSection = ConfigurationManager.GetSection(ConfigurationSettingsReader.DefaultSectionName);
|
||||
if (autofacSection != null)
|
||||
builder.RegisterModule(new ConfigurationSettingsReader());
|
||||
|
||||
|
||||
var optionalHostConfig = HostingEnvironment.MapPath("~/Config/Host.config");
|
||||
if (File.Exists(optionalHostConfig))
|
||||
builder.RegisterModule(new ConfigurationSettingsReader(ConfigurationSettingsReader.DefaultSectionName, optionalHostConfig));
|
||||
|
@@ -1,7 +1,11 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Environment.Topology;
|
||||
using Orchard.Environment.Topology.Models;
|
||||
using Orchard.Logging;
|
||||
|
||||
namespace Orchard.Environment.ShellBuilders {
|
||||
public class DefaultShellContextFactory : IShellContextFactory {
|
||||
@@ -16,30 +20,70 @@ namespace Orchard.Environment.ShellBuilders {
|
||||
_topologyDescriptorCache = topologyDescriptorCache;
|
||||
_compositionStrategy = compositionStrategy;
|
||||
_shellContainerFactory = shellContainerFactory;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public ShellContext Create(ShellSettings settings) {
|
||||
var cachedTopology = _topologyDescriptorCache.Fetch(settings.Name);
|
||||
// handle null-(e.g. cache miss)
|
||||
|
||||
var topology = _compositionStrategy.Compose(cachedTopology);
|
||||
var shellScope = _shellContainerFactory.CreateContainer(topology);
|
||||
|
||||
ShellTopologyDescriptor currentTopology;
|
||||
using (var standaloneEnvironment = new StandaloneEnvironment(shellScope)) {
|
||||
var topologyDescriptorProvider = standaloneEnvironment.Resolve<ITopologyDescriptorManager>();
|
||||
currentTopology = topologyDescriptorProvider.GetTopologyDescriptor();
|
||||
if (settings == null) {
|
||||
return CreateSetupContext();
|
||||
}
|
||||
|
||||
if (cachedTopology.SerialNumber != currentTopology.SerialNumber) {
|
||||
_topologyDescriptorCache.Store(settings.Name, currentTopology);
|
||||
topology = _compositionStrategy.Compose(currentTopology);
|
||||
Logger.Debug("Creating shell context for tenant {0}", settings.Name);
|
||||
|
||||
var cachedDescriptor = _topologyDescriptorCache.Fetch(settings.Name);
|
||||
if (cachedDescriptor == null) {
|
||||
Logger.Information("No topology cached. Starting with minimum components.");
|
||||
cachedDescriptor = new ShellTopologyDescriptor {
|
||||
SerialNumber = 0,
|
||||
EnabledFeatures = Enumerable.Empty<TopologyFeature>(),
|
||||
Parameters = Enumerable.Empty<TopologyParameter>(),
|
||||
};
|
||||
}
|
||||
// handle null-(e.g. cache miss)
|
||||
|
||||
var topology = _compositionStrategy.Compose(cachedDescriptor);
|
||||
var shellScope = _shellContainerFactory.CreateContainer(topology);
|
||||
|
||||
ShellTopologyDescriptor currentDescriptor;
|
||||
using (var standaloneEnvironment = new StandaloneEnvironment(shellScope)) {
|
||||
var topologyDescriptorProvider = standaloneEnvironment.Resolve<ITopologyDescriptorManager>();
|
||||
currentDescriptor = topologyDescriptorProvider.GetTopologyDescriptor();
|
||||
}
|
||||
|
||||
if (cachedDescriptor.SerialNumber != currentDescriptor.SerialNumber) {
|
||||
Logger.Information("Newer topology obtained. Rebuilding shell container.");
|
||||
|
||||
_topologyDescriptorCache.Store(settings.Name, currentDescriptor);
|
||||
topology = _compositionStrategy.Compose(currentDescriptor);
|
||||
shellScope = _shellContainerFactory.CreateContainer(topology);
|
||||
}
|
||||
|
||||
return new ShellContext {
|
||||
Settings = settings,
|
||||
TopologyDescriptor = currentTopology,
|
||||
TopologyDescriptor = currentDescriptor,
|
||||
Topology = topology,
|
||||
LifetimeScope = shellScope,
|
||||
Shell = shellScope.Resolve<IOrchardShell>(),
|
||||
};
|
||||
}
|
||||
|
||||
private ShellContext CreateSetupContext() {
|
||||
Logger.Warning("No shell settings available. Creating shell context for setup");
|
||||
|
||||
var settings = new ShellSettings { Name = "__Orchard__Setup__" };
|
||||
var descriptor = new ShellTopologyDescriptor {
|
||||
SerialNumber = -1,
|
||||
EnabledFeatures = new[] { new TopologyFeature { Name = "Orchard.Setup" } },
|
||||
};
|
||||
|
||||
var topology = _compositionStrategy.Compose(descriptor);
|
||||
var shellScope = _shellContainerFactory.CreateContainer(topology);
|
||||
|
||||
return new ShellContext {
|
||||
Settings = settings,
|
||||
TopologyDescriptor = descriptor,
|
||||
Topology = topology,
|
||||
LifetimeScope = shellScope,
|
||||
Shell = shellScope.Resolve<IOrchardShell>(),
|
||||
|
@@ -1,7 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Orchard.Environment.Topology.Models {
|
||||
public class ShellTopologyDescriptor {
|
||||
public ShellTopologyDescriptor() {
|
||||
EnabledFeatures = Enumerable.Empty<TopologyFeature>();
|
||||
Parameters = Enumerable.Empty<TopologyParameter>();
|
||||
}
|
||||
|
||||
public int SerialNumber { get; set; }
|
||||
public IEnumerable<TopologyFeature> EnabledFeatures { get; set; }
|
||||
public IEnumerable<TopologyParameter> Parameters { get; set; }
|
||||
|
@@ -126,7 +126,6 @@
|
||||
<Compile Include="Environment\DefaultCompositionStrategy.cs" />
|
||||
<Compile Include="Environment\DefaultOrchardHost.cs" />
|
||||
<Compile Include="Mvc\OrchardControllerFactory.cs" />
|
||||
<Compile Include="Environment\HostContext.cs" />
|
||||
<Compile Include="Environment\IOrchardHost.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Validation\Argument.cs" />
|
||||
|
Reference in New Issue
Block a user