From 0c6ae8b8d75cb2917359514ccbc9c1c48d8cd9cb Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Fri, 23 Apr 2010 17:05:28 -0700 Subject: [PATCH] Nearly working integration of multi tenancy components Tenant service provides refresh signal to host (temporary need) Setup module changed to run in any named shell that is uninitialized Table prefix added to setup form (for when sql server option is selected) CreateSetupContext takes shellsettings to support uninitialized tenants Removed name on default route provider - adding several routes by same name not allowed in single appdomain --HG-- branch : dev --- .../Bindings/OrchardSiteFactory.cs | 11 +++ src/Orchard.Specs/Bindings/WebAppHosting.cs | 8 ++ src/Orchard.Specs/Hosting/RequestDetails.cs | 1 + .../Hosting/RequestExtensions.cs | 4 + src/Orchard.Specs/Hosting/WebHost.cs | 3 + src/Orchard.Specs/MultiTenancy.feature | 33 +++++++ src/Orchard.Specs/MultiTenancy.feature.cs | 94 ++++++++++++++++++- .../Environment/RunningShellTableTests.cs | 46 +++++++++ .../DefaultShellContextFactoryTests.cs | 2 +- .../Services/TenantService.cs | 9 +- .../Controllers/SetupController.cs | 20 ++-- .../ViewModels/SetupViewModel.cs | 3 + .../Orchard.Setup/Views/Setup/Index.ascx | 4 + .../Configuration/ShellSettings.cs | 14 +++ src/Orchard/Environment/DefaultOrchardHost.cs | 9 +- src/Orchard/Environment/RunningShellTable.cs | 5 - .../ShellBuilders/ShellContextFactory.cs | 6 +- .../Mvc/ModelBinders/ModelBinderPublisher.cs | 3 +- .../Mvc/Routes/DefaultRouteProvider.cs | 3 +- 19 files changed, 254 insertions(+), 24 deletions(-) diff --git a/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs b/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs index 7378fb141..423c8980a 100644 --- a/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs +++ b/src/Orchard.Specs/Bindings/OrchardSiteFactory.cs @@ -53,5 +53,16 @@ namespace Orchard.Specs.Bindings { }); } + + + [When(@"I cycle the app domain")] + public void WhenICycleTheAppDomain() { + var webApp = Binding(); + webApp.Host.Execute(() => { + Trace.WriteLine("This call to Host.Reinitialize should not be needed, eventually"); + MvcApplication.Host.Reinitialize_Obsolete(); + }); + + } } } diff --git a/src/Orchard.Specs/Bindings/WebAppHosting.cs b/src/Orchard.Specs/Bindings/WebAppHosting.cs index b8f709612..6b6fa82a5 100644 --- a/src/Orchard.Specs/Bindings/WebAppHosting.cs +++ b/src/Orchard.Specs/Bindings/WebAppHosting.cs @@ -119,6 +119,14 @@ namespace Orchard.Specs.Bindings { } + [When(@"I go to ""(.*)"" on host (.*)")] + public void WhenIGoToPathOnHost(string urlPath, string host) { + Host.HostName = host; + _details = Host.SendRequest(urlPath); + _doc = new HtmlDocument(); + _doc.Load(new StringReader(_details.ResponseText)); + } + [When(@"I go to ""(.*)""")] public void WhenIGoTo(string urlPath) { _details = Host.SendRequest(urlPath); diff --git a/src/Orchard.Specs/Hosting/RequestDetails.cs b/src/Orchard.Specs/Hosting/RequestDetails.cs index 7309cf8e2..d5ab6f3ca 100644 --- a/src/Orchard.Specs/Hosting/RequestDetails.cs +++ b/src/Orchard.Specs/Hosting/RequestDetails.cs @@ -12,6 +12,7 @@ namespace Orchard.Specs.Hosting { ResponseHeaders = new Dictionary(); } + public string HostName { get; set; } public string UrlPath { get; set; } public string Page { get; set; } public string Query { get; set; } diff --git a/src/Orchard.Specs/Hosting/RequestExtensions.cs b/src/Orchard.Specs/Hosting/RequestExtensions.cs index f0a55a0b3..dc7271b83 100644 --- a/src/Orchard.Specs/Hosting/RequestExtensions.cs +++ b/src/Orchard.Specs/Hosting/RequestExtensions.cs @@ -16,6 +16,7 @@ namespace Orchard.Specs.Hosting { var physicalPath = Bleroy.FluentPath.Path.Get(webHost.PhysicalDirectory); var details = new RequestDetails { + HostName = webHost.HostName, UrlPath = urlPath, Page = physicalPath .Combine(urlPath.TrimStart('/', '\\')) @@ -89,6 +90,9 @@ namespace Orchard.Specs.Hosting { if (_details.RequestHeaders.TryGetValue("Cookie", out value)) return value; } + else if (index==HeaderHost) { + return _details.HostName; + } return base.GetKnownRequestHeader(index); } diff --git a/src/Orchard.Specs/Hosting/WebHost.cs b/src/Orchard.Specs/Hosting/WebHost.cs index 97c95657c..c188f76e7 100644 --- a/src/Orchard.Specs/Hosting/WebHost.cs +++ b/src/Orchard.Specs/Hosting/WebHost.cs @@ -11,6 +11,7 @@ namespace Orchard.Specs.Hosting { private Path _tempSite; private Path _orchardWebPath; + public void Initialize(string templateName, string virtualDirectory) { var baseDir = Path.Get(AppDomain.CurrentDomain.BaseDirectory); @@ -29,6 +30,7 @@ namespace Orchard.Specs.Hosting { .ShallowCopy("*.dll", _tempSite.Combine("bin")) .ShallowCopy("*.pdb", _tempSite.Combine("bin")); + HostName = "localhost"; PhysicalDirectory = _tempSite; VirtualDirectory = virtualDirectory; @@ -44,6 +46,7 @@ namespace Orchard.Specs.Hosting { sourceModule.Combine("Views").DeepCopy(targetModule.Combine("Views")); } + public string HostName { get; set; } public string PhysicalDirectory { get; private set; } public string VirtualDirectory { get; private set; } diff --git a/src/Orchard.Specs/MultiTenancy.feature b/src/Orchard.Specs/MultiTenancy.feature index 9921e4121..a32b0ab39 100644 --- a/src/Orchard.Specs/MultiTenancy.feature +++ b/src/Orchard.Specs/MultiTenancy.feature @@ -41,3 +41,36 @@ Scenario: A new tenant is created with uninitialized state And I am redirected Then I should see "Uninitialized" And the status should be 200 OK + +Scenario: A new tenant goes to the setup screen + Given I have installed Orchard + And I have installed "Orchard.MultiTenancy" + When I go to "Admin/MultiTenancy/Add" + And I fill in + | name | value | + | Name | Scott | + | RequestUrlHost | scott.example.org | + And I hit "Save" + And I go to "/Setup" on host scott.example.org + Then I should see "Welcome to Orchard" + And I should see "Finish Setup" + And the status should be 200 OK + +Scenario: A new tenant runs the setup + Given I have installed Orchard + And I have installed "Orchard.MultiTenancy" + When I go to "Admin/MultiTenancy/Add" + And I fill in + | name | value | + | Name | Scott | + | RequestUrlHost | scott.example.org | + And I hit "Save" + And I go to "/Setup" on host scott.example.org + And I fill in + | name | value | + | SiteName | Scott Site | + | AdminPassword | 6655321 | + And I hit "Finish Setup" + And I go to "/Default.aspx" + Then I should see "

Scott Site

" + And I should see "Welcome, admin!" diff --git a/src/Orchard.Specs/MultiTenancy.feature.cs b/src/Orchard.Specs/MultiTenancy.feature.cs index dc94db983..4dd7fc195 100644 --- a/src/Orchard.Specs/MultiTenancy.feature.cs +++ b/src/Orchard.Specs/MultiTenancy.feature.cs @@ -2,7 +2,7 @@ // // This code was generated by SpecFlow (http://www.specflow.org/). // SpecFlow Version:1.2.0.0 -// Runtime Version:2.0.50727.3603 +// Runtime Version:2.0.50727.4927 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -158,6 +158,98 @@ this.ScenarioSetup(scenarioInfo); testRunner.Then("I should see \"Uninitialized\""); #line 43 testRunner.And("the status should be 200 OK"); +#line hidden + testRunner.CollectScenarioErrors(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("A new tenant goes to the setup screen")] + public virtual void ANewTenantGoesToTheSetupScreen() + { + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("A new tenant goes to the setup screen", ((string[])(null))); +#line 45 +this.ScenarioSetup(scenarioInfo); +#line 46 + testRunner.Given("I have installed Orchard"); +#line 47 + testRunner.And("I have installed \"Orchard.MultiTenancy\""); +#line 48 + testRunner.When("I go to \"Admin/MultiTenancy/Add\""); +#line hidden + TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] { + "name", + "value"}); + table3.AddRow(new string[] { + "Name", + "Scott"}); + table3.AddRow(new string[] { + "RequestUrlHost", + "scott.example.org"}); +#line 49 + testRunner.And("I fill in", ((string)(null)), table3); +#line 53 + testRunner.And("I hit \"Save\""); +#line 54 + testRunner.And("I go to \"/Setup\" on host scott.example.org"); +#line 55 + testRunner.Then("I should see \"Welcome to Orchard\""); +#line 56 + testRunner.And("I should see \"Finish Setup\""); +#line 57 + testRunner.And("the status should be 200 OK"); +#line hidden + testRunner.CollectScenarioErrors(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("A new tenant runs the setup")] + public virtual void ANewTenantRunsTheSetup() + { + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("A new tenant runs the setup", ((string[])(null))); +#line 59 +this.ScenarioSetup(scenarioInfo); +#line 60 + testRunner.Given("I have installed Orchard"); +#line 61 + testRunner.And("I have installed \"Orchard.MultiTenancy\""); +#line 62 + testRunner.When("I go to \"Admin/MultiTenancy/Add\""); +#line hidden + TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] { + "name", + "value"}); + table4.AddRow(new string[] { + "Name", + "Scott"}); + table4.AddRow(new string[] { + "RequestUrlHost", + "scott.example.org"}); +#line 63 + testRunner.And("I fill in", ((string)(null)), table4); +#line 67 + testRunner.And("I hit \"Save\""); +#line 68 + testRunner.And("I go to \"/Setup\" on host scott.example.org"); +#line hidden + TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] { + "name", + "value"}); + table5.AddRow(new string[] { + "SiteName", + "Scott Site"}); + table5.AddRow(new string[] { + "AdminPassword", + "6655321"}); +#line 69 + testRunner.And("I fill in", ((string)(null)), table5); +#line 73 + testRunner.And("I hit \"Finish Setup\""); +#line 74 + testRunner.And("I go to \"/Default.aspx\""); +#line 75 + testRunner.Then("I should see \"

Scott Site

\""); +#line 76 + testRunner.And("I should see \"Welcome, admin!\""); #line hidden testRunner.CollectScenarioErrors(); } diff --git a/src/Orchard.Tests/Environment/RunningShellTableTests.cs b/src/Orchard.Tests/Environment/RunningShellTableTests.cs index 6dac36484..3c0c1bb80 100644 --- a/src/Orchard.Tests/Environment/RunningShellTableTests.cs +++ b/src/Orchard.Tests/Environment/RunningShellTableTests.cs @@ -162,5 +162,51 @@ namespace Orchard.Tests.Environment { Assert.That(table.Match(new StubHttpContext("~/bar/foo", "wiki.example.com")), Is.Null); } + [Test] + public void HostNameMatchesRightmostIfRequestIsLonger() { + var table = (IRunningShellTable) new RunningShellTable(); + var settings = new ShellSettings {Name = "Default"}; + var settingsA = new ShellSettings {Name = "Alpha", RequestUrlHost = "example.com"}; + table.Add(settings); + table.Add(settingsA); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "www.example.com")), Is.SameAs(settingsA)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "wiki.example.com")), Is.SameAs(settingsA)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "example.com")), Is.SameAs(settingsA)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "localhost")), Is.SameAs(settings)); + } + + [Test] + public void LongestMatchingHostHasPriority() { + var table = (IRunningShellTable) new RunningShellTable(); + var settings = new ShellSettings {Name = "Default"}; + var settingsA = new ShellSettings {Name = "Alpha", RequestUrlHost = "www.example.com"}; + var settingsB = new ShellSettings {Name = "Beta", RequestUrlHost = "example.com"}; + var settingsG = new ShellSettings {Name = "Gamma", RequestUrlHost = "wiki.example.com"}; + table.Add(settings); + table.Add(settingsA); + table.Add(settingsB); + table.Add(settingsG); + + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "www.example.com")), Is.SameAs(settingsA)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "wiki.example.com")), Is.SameAs(settingsG)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "username.example.com")), Is.SameAs(settingsB)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "localhost")), Is.SameAs(settings)); + } + + + [Test] + public void ShellNameUsedToDistinctThingsAsTheyAreAdded() { + var table = (IRunningShellTable)new RunningShellTable(); + var settings = new ShellSettings { Name = "Default" }; + var settingsA = new ShellSettings { Name = "Alpha", RequestUrlHost = "removed.example.com" }; + var settingsB = new ShellSettings { Name = "Alpha", RequestUrlHost = "added.example.com" }; + table.Add(settings); + table.Add(settingsA); + table.Add(settingsB); + + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "removed.example.com")), Is.SameAs(settings)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "added.example.com")), Is.SameAs(settingsB)); + Assert.That(table.Match(new StubHttpContext("~/foo/bar", "localhost")), Is.SameAs(settings)); + } } } diff --git a/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs b/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs index 9c7645970..e55615b2a 100644 --- a/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs +++ b/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs @@ -75,7 +75,7 @@ namespace Orchard.Tests.Environment.ShellBuilders { .Returns(_container.BeginLifetimeScope("shell")); var factory = _container.Resolve(); - var context = factory.CreateSetupContext(); + var context = factory.CreateSetupContext(new ShellSettings { Name = "Default" }); Assert.That(context.Descriptor.EnabledFeatures, Has.Some.With.Property("Name").EqualTo("Orchard.Setup")); } diff --git a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Services/TenantService.cs b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Services/TenantService.cs index e4d5006fe..f4fd6ecbd 100644 --- a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Services/TenantService.cs +++ b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Services/TenantService.cs @@ -1,12 +1,15 @@ using System.Collections.Generic; +using Orchard.Environment; using Orchard.Environment.Configuration; namespace Orchard.MultiTenancy.Services { public class TenantService : ITenantService { private readonly IShellSettingsManager _shellSettingsManager; + private readonly IOrchardHost _orchardHost; - public TenantService(IShellSettingsManager shellSettingsManager) { + public TenantService(IShellSettingsManager shellSettingsManager, IOrchardHost orchardHost) { _shellSettingsManager = shellSettingsManager; + _orchardHost = orchardHost; } #region Implementation of ITenantService @@ -17,6 +20,10 @@ namespace Orchard.MultiTenancy.Services { public void CreateTenant(ShellSettings settings) { _shellSettingsManager.SaveSettings(settings); + + + // MultiTenancy: This will not be needed when host listens to event bus + _orchardHost.Reinitialize_Obsolete(); } #endregion diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Controllers/SetupController.cs b/src/Orchard.Web/Modules/Orchard.Setup/Controllers/SetupController.cs index cd6ac207b..88592c1ac 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Controllers/SetupController.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/Controllers/SetupController.cs @@ -23,6 +23,7 @@ using Orchard.UI.Notify; namespace Orchard.Setup.Controllers { [ValidateInput(false)] public class SetupController : Controller { + private readonly ShellSettings _shellSettings; private readonly INotifier _notifier; private readonly IOrchardHost _orchardHost; private readonly IShellSettingsManager _shellSettingsManager; @@ -31,12 +32,14 @@ namespace Orchard.Setup.Controllers { private readonly IAppDataFolder _appDataFolder; public SetupController( + ShellSettings shellSettings, INotifier notifier, IOrchardHost orchardHost, IShellSettingsManager shellSettingsManager, IShellContainerFactory shellContainerFactory, ICompositionStrategy compositionStrategy, IAppDataFolder appDataFolder) { + _shellSettings = shellSettings; _notifier = notifier; _orchardHost = orchardHost; _shellSettingsManager = shellSettingsManager; @@ -75,10 +78,10 @@ namespace Orchard.Setup.Controllers { } try { - var shellSettings = new ShellSettings { - Name = "Default", + var shellSettings = new ShellSettings(_shellSettings) { DataProvider = model.DatabaseOptions ? "SQLite" : "SqlServer", - DataConnectionString = model.DatabaseConnectionString + DataConnectionString = model.DatabaseConnectionString, + DataTablePrefix = model.DatabaseTablePrefix, }; // The vanilla Orchard distibution has the following modules enabled. @@ -99,10 +102,10 @@ namespace Orchard.Setup.Controllers { var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellToplogy); using (var environment = new StandaloneEnvironment(bootstrapLifetimeScope)) { environment.Resolve().CreateDatabase(); - + environment.Resolve().UpdateShellDescriptor( - 0, - shellDescriptor.EnabledFeatures, + 0, + shellDescriptor.EnabledFeatures, shellDescriptor.Parameters); } @@ -110,6 +113,9 @@ namespace Orchard.Setup.Controllers { // creating a standalone environment. // in theory this environment can be used to resolve any normal components by interface, and those // components will exist entirely in isolation - no crossover between the safemode container currently in effect + + // must mark state as Running - otherwise standalone enviro is created "for setup" + shellSettings.State = new TenantState("Running"); using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) { try { // create superuser @@ -165,9 +171,9 @@ namespace Orchard.Setup.Controllers { } } - shellSettings.State = new TenantState("Running"); _shellSettingsManager.SaveSettings(shellSettings); + // MultiTenancy: This will not be needed when host listens to event bus _orchardHost.Reinitialize_Obsolete(); // redirect to the welcome page. diff --git a/src/Orchard.Web/Modules/Orchard.Setup/ViewModels/SetupViewModel.cs b/src/Orchard.Web/Modules/Orchard.Setup/ViewModels/SetupViewModel.cs index 88d1cb3e1..122c38e77 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/ViewModels/SetupViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/ViewModels/SetupViewModel.cs @@ -1,3 +1,4 @@ +using System; using System.ComponentModel.DataAnnotations; using Orchard.Setup.Annotations; using Orchard.Mvc.ViewModels; @@ -17,5 +18,7 @@ namespace Orchard.Setup.ViewModels { public bool DatabaseOptions { get; set; } [SqlDatabaseConnectionString] public string DatabaseConnectionString { get; set; } + + public string DatabaseTablePrefix { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Views/Setup/Index.ascx b/src/Orchard.Web/Modules/Orchard.Setup/Views/Setup/Index.ascx index f87b48449..cfc7135e3 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Views/Setup/Index.ascx +++ b/src/Orchard.Web/Modules/Orchard.Setup/Views/Setup/Index.ascx @@ -35,6 +35,10 @@ using (Html.BeginFormAntiForgeryPost()) { %> <%=Html.EditorFor(svm => svm.DatabaseConnectionString)%> <%=_Encoded("Example:") %>
<%=_Encoded("Data Source=sqlServerName;Initial Catalog=dbName;Persist Security Info=True;User ID=userName;Password=password") %>
+ + + <%=Html.EditorFor(svm => svm.DatabaseTablePrefix)%> +
diff --git a/src/Orchard/Environment/Configuration/ShellSettings.cs b/src/Orchard/Environment/Configuration/ShellSettings.cs index bf1bf36ff..c6717938f 100644 --- a/src/Orchard/Environment/Configuration/ShellSettings.cs +++ b/src/Orchard/Environment/Configuration/ShellSettings.cs @@ -5,6 +5,20 @@ /// from the App_Data settings.txt files. /// public class ShellSettings { + public ShellSettings() { + State = new TenantState("Invalid"); + } + + public ShellSettings(ShellSettings settings) { + Name = settings.Name; + DataProvider = settings.DataProvider; + DataConnectionString = settings.DataConnectionString; + DataTablePrefix = settings.DataTablePrefix; + RequestUrlHost = settings.RequestUrlHost; + RequestUrlPrefix = settings.RequestUrlPrefix; + State = settings.State; + } + public string Name { get; set; } public string DataProvider { get; set; } diff --git a/src/Orchard/Environment/DefaultOrchardHost.cs b/src/Orchard/Environment/DefaultOrchardHost.cs index a2a0ce27f..3f6e182d3 100644 --- a/src/Orchard/Environment/DefaultOrchardHost.cs +++ b/src/Orchard/Environment/DefaultOrchardHost.cs @@ -96,11 +96,16 @@ namespace Orchard.Environment { } ShellContext CreateSetupContext() { - Logger.Debug("Creating shell context for setup"); - return _shellContextFactory.CreateSetupContext(); + Logger.Debug("Creating shell context for root setup"); + return _shellContextFactory.CreateSetupContext(new ShellSettings { Name = "Default" }); } ShellContext CreateShellContext(ShellSettings settings) { + if (settings.State.CurrentState == TenantState.State.Uninitialized) { + Logger.Debug("Creating shell context for tenant {0} setup", settings.Name); + return _shellContextFactory.CreateSetupContext(settings); + } + Logger.Debug("Creating shell context for tenant {0}", settings.Name); return _shellContextFactory.CreateShellContext(settings); } diff --git a/src/Orchard/Environment/RunningShellTable.cs b/src/Orchard/Environment/RunningShellTable.cs index 6efaa53d5..ca96ecadc 100644 --- a/src/Orchard/Environment/RunningShellTable.cs +++ b/src/Orchard/Environment/RunningShellTable.cs @@ -8,7 +8,6 @@ using Orchard.Environment.Configuration; namespace Orchard.Environment { public interface IRunningShellTable { void Add(ShellSettings settings); - IEnumerable List(); ShellSettings Match(HttpContextBase httpContext); } @@ -50,10 +49,6 @@ namespace Orchard.Environment { } } - public IEnumerable List() { - return _shells; - } - public ShellSettings Match(HttpContextBase httpContext) { var host = httpContext.Request.ServerVariables.Get("HTTP_HOST") ?? ""; diff --git a/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs b/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs index f3e5e4564..8321a26e9 100644 --- a/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs +++ b/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs @@ -20,7 +20,7 @@ namespace Orchard.Environment.ShellBuilders { /// Builds a shell context for an uninitialized Orchard instance. Needed /// to display setup user interface. /// - ShellContext CreateSetupContext(); + ShellContext CreateSetupContext(ShellSettings settings); } public class ShellContextFactory : IShellContextFactory { @@ -87,11 +87,9 @@ namespace Orchard.Environment.ShellBuilders { }; } - public ShellContext CreateSetupContext() { + public ShellContext CreateSetupContext(ShellSettings settings) { Logger.Warning("No shell settings available. Creating shell context for setup"); - var settings = new ShellSettings { Name = "Default" }; - var descriptor = new ShellDescriptor { SerialNumber = -1, EnabledFeatures = new[] { new ShellFeature { Name = "Orchard.Setup" } }, diff --git a/src/Orchard/Mvc/ModelBinders/ModelBinderPublisher.cs b/src/Orchard/Mvc/ModelBinders/ModelBinderPublisher.cs index 011616ceb..52e5607fd 100644 --- a/src/Orchard/Mvc/ModelBinders/ModelBinderPublisher.cs +++ b/src/Orchard/Mvc/ModelBinders/ModelBinderPublisher.cs @@ -10,8 +10,9 @@ namespace Orchard.Mvc.ModelBinders { } public void Publish(IEnumerable binders) { + // MultiTenancy: should hook default model binder instead and rely on shell-specific binders (instead adding to type dictionary) foreach (var descriptor in binders) { - _binders.Add(descriptor.Type, descriptor.ModelBinder); + _binders[descriptor.Type] = descriptor.ModelBinder; } } } diff --git a/src/Orchard/Mvc/Routes/DefaultRouteProvider.cs b/src/Orchard/Mvc/Routes/DefaultRouteProvider.cs index 5a087e396..5bf66bba6 100644 --- a/src/Orchard/Mvc/Routes/DefaultRouteProvider.cs +++ b/src/Orchard/Mvc/Routes/DefaultRouteProvider.cs @@ -8,8 +8,7 @@ namespace Orchard.Mvc.Routes { public class DefaultRouteProvider : IRouteProvider { public IEnumerable GetRoutes() { return new[] { - new RouteDescriptor { - Name = "Default", + new RouteDescriptor { Priority = -20, Route = new Route( "{controller}/{action}/{id}",