diff --git a/src/Orchard.Tests/Environment/DefaultCompositionStrategyTests.cs b/src/Orchard.Tests/Environment/DefaultCompositionStrategyTests.cs index a6d20e3f2..dc964d96f 100644 --- a/src/Orchard.Tests/Environment/DefaultCompositionStrategyTests.cs +++ b/src/Orchard.Tests/Environment/DefaultCompositionStrategyTests.cs @@ -8,6 +8,7 @@ using Autofac.Core; using Moq; using NUnit.Framework; using Orchard.ContentManagement.Records; +using Orchard.Environment.Configuration; using Orchard.Environment.Extensions; using Orchard.Environment.Extensions.Models; using Orchard.Environment.Topology; @@ -51,16 +52,21 @@ namespace Orchard.Tests.Environment { }); } + private static ShellSettings BuildDefaultSettings() { + return new ShellSettings { Name = "Default" }; + } + [Test] public void TopologyIsNotNull() { var descriptor = Build.TopologyDescriptor(); var compositionStrategy = _container.Resolve(); - var topology = compositionStrategy.Compose(descriptor); + var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor); Assert.That(topology, Is.Not.Null); } + [Test] public void DependenciesFromFeatureArePutIntoTopology() { var descriptor = Build.TopologyDescriptor().WithFeatures("Foo", "Bar"); @@ -74,7 +80,7 @@ namespace Orchard.Tests.Environment { _featureTypes["Bar"] = new[] { typeof(BarService1) }; var compositionStrategy = _container.Resolve(); - var topology = compositionStrategy.Compose(descriptor); + var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor); Assert.That(topology, Is.Not.Null); Assert.That(topology.Dependencies.Count(), Is.EqualTo(2)); @@ -115,7 +121,7 @@ namespace Orchard.Tests.Environment { _featureTypes["Foo"] = new[] { typeof(FooService1) }; var compositionStrategy = _container.Resolve(); - var topology = compositionStrategy.Compose(descriptor); + var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor); var foo = topology.Dependencies.SingleOrDefault(t => t.Type == typeof(FooService1)); Assert.That(foo, Is.Not.Null); @@ -137,9 +143,9 @@ namespace Orchard.Tests.Environment { _featureTypes["Bar"] = new[] { typeof(BetaModule) }; var compositionStrategy = _container.Resolve(); - var topology = compositionStrategy.Compose(descriptor); + var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor); - var alpha = topology.Dependencies.Single(x => x.Type == typeof (AlphaModule)); + var alpha = topology.Dependencies.Single(x => x.Type == typeof(AlphaModule)); var beta = topology.Dependencies.Single(x => x.Type == typeof(BetaModule)); Assert.That(alpha.Feature.Descriptor.Name, Is.EqualTo("Foo")); @@ -170,11 +176,11 @@ namespace Orchard.Tests.Environment { _featureTypes["Bar Minus"] = new[] { typeof(DeltaController), typeof(EpsilonController) }; var compositionStrategy = _container.Resolve(); - var topology = compositionStrategy.Compose(descriptor); + var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor); - var gamma = topology.Controllers.Single(x => x.Type == typeof (GammaController)); - var delta = topology.Controllers.Single(x => x.Type == typeof (DeltaController)); - var epsilon = topology.Controllers.Single(x => x.Type == typeof (EpsilonController)); + var gamma = topology.Controllers.Single(x => x.Type == typeof(GammaController)); + var delta = topology.Controllers.Single(x => x.Type == typeof(DeltaController)); + var epsilon = topology.Controllers.Single(x => x.Type == typeof(EpsilonController)); Assert.That(gamma.Feature.Descriptor.Name, Is.EqualTo("Foo Plus")); Assert.That(gamma.AreaName, Is.EqualTo("MyCompany.Foo")); @@ -189,7 +195,7 @@ namespace Orchard.Tests.Environment { Assert.That(epsilon.ControllerName, Is.EqualTo("Epsilon")); } - + public class GammaController : Controller { } @@ -205,7 +211,7 @@ namespace Orchard.Tests.Environment { } } - + [Test] public void RecordsArePutIntoTopologyWithTableName() { var descriptor = Build.TopologyDescriptor().WithFeatures("Foo Plus", "Bar", "Bar Minus"); @@ -221,10 +227,10 @@ namespace Orchard.Tests.Environment { _featureTypes["Bar Minus"] = Enumerable.Empty(); var compositionStrategy = _container.Resolve(); - var topology = compositionStrategy.Compose(descriptor); + var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor); - var foo = topology.Records.Single(x => x.Type == typeof (FooRecord)); - var bar = topology.Records.Single(x => x.Type == typeof (BarRecord)); + var foo = topology.Records.Single(x => x.Type == typeof(FooRecord)); + var bar = topology.Records.Single(x => x.Type == typeof(BarRecord)); Assert.That(foo.Feature.Descriptor.Name, Is.EqualTo("Foo Plus")); Assert.That(foo.TableName, Is.EqualTo("MyCompany_Foo_FooRecord")); @@ -236,14 +242,14 @@ namespace Orchard.Tests.Environment { [Test] public void CoreRecordsAreAddedAutomatically() { var descriptor = Build.TopologyDescriptor().WithFeatures("Orchard.Framework"); - - var compositionStrategy = _container.Resolve(); - var topology = compositionStrategy.Compose(descriptor); - var ct = topology.Records.Single(x => x.Type == typeof (ContentTypeRecord)); - var ci = topology.Records.Single(x => x.Type == typeof (ContentItemRecord)); - var civ = topology.Records.Single(x => x.Type == typeof (ContentItemVersionRecord)); - + var compositionStrategy = _container.Resolve(); + var topology = compositionStrategy.Compose(BuildDefaultSettings(), descriptor); + + var ct = topology.Records.Single(x => x.Type == typeof(ContentTypeRecord)); + var ci = topology.Records.Single(x => x.Type == typeof(ContentItemRecord)); + var civ = topology.Records.Single(x => x.Type == typeof(ContentItemVersionRecord)); + Assert.That(ct.Feature.Descriptor.Name, Is.EqualTo("Orchard.Framework")); Assert.That(ct.TableName, Is.EqualTo("Orchard_Framework_ContentTypeRecord")); @@ -252,6 +258,36 @@ namespace Orchard.Tests.Environment { Assert.That(civ.Feature.Descriptor.Name, Is.EqualTo("Orchard.Framework")); Assert.That(civ.TableName, Is.EqualTo("Orchard_Framework_ContentItemVersionRecord")); - } + } + + [Test] + public void DataPrefixChangesTableName() { + var settings = BuildDefaultSettings(); + settings.DataPrefix = "Yadda"; + var descriptor = Build.TopologyDescriptor().WithFeatures("Foo Plus", "Bar", "Bar Minus"); + + _extensionDescriptors = new[] { + Build.ExtensionDescriptor("MyCompany.Foo", "Foo").WithFeatures("Foo", "Foo Plus"), + Build.ExtensionDescriptor("Bar").WithFeatures("Bar", "Bar Minus"), + }; + + _featureTypes["Foo"] = Enumerable.Empty(); + _featureTypes["Foo Plus"] = new[] { typeof(FooRecord) }; + _featureTypes["Bar"] = new[] { typeof(BarRecord) }; + _featureTypes["Bar Minus"] = Enumerable.Empty(); + + var compositionStrategy = _container.Resolve(); + var topology = compositionStrategy.Compose(settings, descriptor); + + var foo = topology.Records.Single(x => x.Type == typeof(FooRecord)); + var bar = topology.Records.Single(x => x.Type == typeof(BarRecord)); + + Assert.That(foo.Feature.Descriptor.Name, Is.EqualTo("Foo Plus")); + Assert.That(foo.TableName, Is.EqualTo("Yadda_MyCompany_Foo_FooRecord")); + + Assert.That(bar.Feature.Descriptor.Name, Is.EqualTo("Bar")); + Assert.That(bar.TableName, Is.EqualTo("Yadda_Bar_BarRecord")); + } + } } diff --git a/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs b/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs index c7f35ec0f..4ee775e37 100644 --- a/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs +++ b/src/Orchard.Tests/Environment/ShellBuilders/DefaultShellContextFactoryTests.cs @@ -34,7 +34,7 @@ namespace Orchard.Tests.Environment.ShellBuilders { .Returns(topologyDescriptor); _container.Mock() - .Setup(x => x.Compose(topologyDescriptor)) + .Setup(x => x.Compose(settings, topologyDescriptor)) .Returns(topology); _container.Mock() @@ -47,7 +47,7 @@ namespace Orchard.Tests.Environment.ShellBuilders { var factory = _container.Resolve(); - var context = factory.Create(settings); + var context = factory.CreateShellContext(settings); Assert.That(context.Settings, Is.SameAs(settings)); Assert.That(context.Descriptor, Is.SameAs(topologyDescriptor)); @@ -58,10 +58,11 @@ namespace Orchard.Tests.Environment.ShellBuilders { [Test] public void NullSettingsReturnsSetupContext() { + var settings = new ShellSettings { Name = "Default" }; var topology = new ShellTopology(); _container.Mock() - .Setup(x => x.Compose(It.IsAny())) + .Setup(x => x.Compose(settings, It.IsAny())) .Returns(topology); _container.Mock() @@ -69,7 +70,7 @@ namespace Orchard.Tests.Environment.ShellBuilders { .Returns(_container.BeginLifetimeScope("shell")); var factory = _container.Resolve(); - var context = factory.Create(null); + var context = factory.CreateShellContext(null); Assert.That(context.Descriptor.EnabledFeatures, Has.Some.With.Property("Name").EqualTo("Orchard.Setup")); } diff --git a/src/Orchard/Environment/DefaultOrchardHost.cs b/src/Orchard/Environment/DefaultOrchardHost.cs index 5ea9f3374..40efcfd31 100644 --- a/src/Orchard/Environment/DefaultOrchardHost.cs +++ b/src/Orchard/Environment/DefaultOrchardHost.cs @@ -92,12 +92,12 @@ namespace Orchard.Environment { ShellContext CreateSetupContext() { Logger.Debug("Creating shell context for setup"); - return _shellContextFactory.Create(null); + return _shellContextFactory.CreateSetupContext(); } ShellContext CreateShellContext(ShellSettings settings) { Logger.Debug("Creating shell context for tenant {0}", settings.Name); - return _shellContextFactory.Create(settings); + return _shellContextFactory.CreateShellContext(settings); } protected virtual void BeginRequest() { diff --git a/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs b/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs index c6dedc78d..0c7546c87 100644 --- a/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs +++ b/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs @@ -6,9 +6,21 @@ using Orchard.Environment.Topology.Models; using Orchard.Logging; namespace Orchard.Environment.ShellBuilders { - + /// + /// High-level coordinator that exercises other component capabilities to + /// build all of the artifacts for a running shell given a tenant settings. + /// public interface IShellContextFactory { - ShellContext Create(ShellSettings settings); + /// + /// Builds a shell context given a specific tenant settings structure + /// + ShellContext CreateShellContext(ShellSettings settings); + + /// + /// Builds a shell context for an uninitialized Orchard instance. Needed + /// to display setup user interface. + /// + ShellContext CreateSetupContext(); } public class ShellContextFactory : IShellContextFactory { @@ -28,10 +40,7 @@ namespace Orchard.Environment.ShellBuilders { public ILogger Logger { get; set; } - public ShellContext Create(ShellSettings settings) { - if (settings == null) { - return CreateSetupContext(); - } + public ShellContext CreateShellContext(ShellSettings settings) { Logger.Debug("Creating shell context for tenant {0}", settings.Name); @@ -41,7 +50,7 @@ namespace Orchard.Environment.ShellBuilders { knownDescriptor = MinimumTopologyDescriptor(); } - var topology = _compositionStrategy.Compose(knownDescriptor); + var topology = _compositionStrategy.Compose(settings, knownDescriptor); var shellScope = _shellContainerFactory.CreateContainer(settings, topology); ShellDescriptor currentDescriptor; @@ -54,7 +63,7 @@ namespace Orchard.Environment.ShellBuilders { Logger.Information("Newer topology obtained. Rebuilding shell container."); _shellDescriptorCache.Store(settings.Name, currentDescriptor); - topology = _compositionStrategy.Compose(currentDescriptor); + topology = _compositionStrategy.Compose(settings, currentDescriptor); shellScope = _shellContainerFactory.CreateContainer(settings, topology); } @@ -78,16 +87,17 @@ namespace Orchard.Environment.ShellBuilders { }; } - private ShellContext CreateSetupContext() { + public ShellContext CreateSetupContext() { Logger.Warning("No shell settings available. Creating shell context for setup"); var settings = new ShellSettings { Name = "__Orchard__Setup__" }; + var descriptor = new ShellDescriptor { SerialNumber = -1, EnabledFeatures = new[] { new ShellFeature { Name = "Orchard.Setup" } }, }; - var topology = _compositionStrategy.Compose(descriptor); + var topology = _compositionStrategy.Compose(settings, descriptor); var shellScope = _shellContainerFactory.CreateContainer(settings, topology); return new ShellContext { diff --git a/src/Orchard/Environment/Topology/CompositionStrategy.cs b/src/Orchard/Environment/Topology/CompositionStrategy.cs index 47faa6c54..c7f7f85ba 100644 --- a/src/Orchard/Environment/Topology/CompositionStrategy.cs +++ b/src/Orchard/Environment/Topology/CompositionStrategy.cs @@ -6,6 +6,7 @@ using System.Web.Mvc; using Autofac.Core; using Orchard.ContentManagement; using Orchard.ContentManagement.Records; +using Orchard.Environment.Configuration; using Orchard.Environment.Extensions; using Orchard.Environment.Extensions.Models; using Orchard.Environment.Topology.Models; @@ -19,7 +20,7 @@ namespace Orchard.Environment.Topology { /// Using information from the IExtensionManager, transforms and populates all of the /// topology model the shell builders will need to correctly initialize a tenant IoC container. /// - ShellTopology Compose(ShellDescriptor descriptor); + ShellTopology Compose(ShellSettings settings, ShellDescriptor descriptor); } public class CompositionStrategy : ICompositionStrategy { @@ -29,7 +30,7 @@ namespace Orchard.Environment.Topology { _extensionManager = extensionManager; } - public ShellTopology Compose(ShellDescriptor descriptor) { + public ShellTopology Compose(ShellSettings settings, ShellDescriptor descriptor) { var enabledFeatures = _extensionManager.AvailableExtensions() .SelectMany(extensionDescriptor => extensionDescriptor.Features) .Where(featureDescriptor => IsFeatureEnabledInTopology(featureDescriptor, descriptor)); @@ -42,7 +43,7 @@ namespace Orchard.Environment.Topology { var modules = BuildTopology(features, IsModule, BuildModule); var dependencies = BuildTopology(features, IsDependency, (t, f) => BuildDependency(t, f, descriptor)); var controllers = BuildTopology(features, IsController, BuildController); - var records = BuildTopology(features, IsRecord, BuildRecord); + var records = BuildTopology(features, IsRecord, (t, f) => BuildRecord(t, f, settings)); return new ShellTopology { Dependencies = dependencies.Concat(modules).ToArray(), @@ -129,14 +130,18 @@ namespace Orchard.Environment.Topology { (!typeof(IContent).IsAssignableFrom(type) || typeof(ContentPartRecord).IsAssignableFrom(type)); } - private static RecordTopology BuildRecord(Type type, Feature feature) { + private static RecordTopology BuildRecord(Type type, Feature feature, ShellSettings settings) { var extensionDescriptor = feature.Descriptor.Extension; var extensionName = extensionDescriptor.Name.Replace('.', '_'); + var dataPrefix = ""; + if (!string.IsNullOrEmpty(settings.DataPrefix)) + dataPrefix = settings.DataPrefix + "_"; + return new RecordTopology { Type = type, Feature = feature, - TableName = extensionName + '_' + type.Name, + TableName = dataPrefix + extensionName + '_' + type.Name, }; } }