Adding a specific component to orchetrate the creation of a shell context

--HG--
branch : dev
This commit is contained in:
Louis DeJardin
2010-04-14 18:22:23 -07:00
parent f6f73cca9c
commit d9598d020f
8 changed files with 185 additions and 6 deletions

View File

@@ -25,8 +25,7 @@ namespace Orchard.Specs.Hosting
webHost.Execute(() =>
{
var output = new StringWriter();
var worker = new Worker(details, output);
HttpRuntime.ProcessRequest(worker);
HttpRuntime.ProcessRequest(new Worker(details, output));
details.ResponseText = output.ToString();
});
@@ -35,8 +34,8 @@ namespace Orchard.Specs.Hosting
class Worker : SimpleWorkerRequest
{
private RequestDetails _details;
private TextWriter _output;
private readonly RequestDetails _details;
private readonly TextWriter _output;
public Worker(RequestDetails details, TextWriter output)
: base(details.Page, details.Query, output)
@@ -60,3 +59,4 @@ namespace Orchard.Specs.Hosting
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Autofac;
using Autofac.Builder;
using Autofac.Core;
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;
namespace Orchard.Tests.Environment.ShellBuilders {
[TestFixture]
public class DefaultShellContextFactoryTests {
private IContainer _container;
[SetUp]
public void Init() {
var builder = new ContainerBuilder();
builder.RegisterType<DefaultShellContextFactory>().As<IShellContextFactory>();
builder.RegisterSource(new MockServiceSource());
_container = builder.Build();
}
[Test]
public void NormalExecutionReturnsExpectedObjects() {
var settings = new ShellSettings {Name = "Default"};
var topologyDescriptor = new ShellTopologyDescriptor {SerialNumber = 6655321};
var topology = new ShellTopology();
ILifetimeScope shellLifetimeScope;
_container.Mock<ITopologyDescriptorCache>()
.Setup(x => x.Fetch("Default"))
.Returns(topologyDescriptor);
_container.Mock<ICompositionStrategy>()
.Setup(x => x.Compose(topologyDescriptor))
.Returns(topology);
_container.Mock<IShellContainerFactory>()
.Setup(x => x.CreateContainer(topology))
.Returns(shellLifetimeScope = _container.BeginLifetimeScope("shell"));
_container.Mock<ITopologyDescriptorProvider>()
.Setup(x => x.GetTopologyDescriptor())
.Returns(topologyDescriptor);
var factory = _container.Resolve<IShellContextFactory>();
var context = factory.Create(settings);
Assert.That(context.Settings, Is.SameAs(settings));
Assert.That(context.TopologyDescriptor, Is.SameAs(topologyDescriptor));
Assert.That(context.Topology, Is.SameAs(topology));
Assert.That(context.LifetimeScope, Is.SameAs(shellLifetimeScope));
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>>();
}
}
}

View File

@@ -163,6 +163,7 @@
<Compile Include="Environment\DefaultOrchardHostTests.cs" />
<Compile Include="Environment\DefaultOrchardShellTests.cs" />
<Compile Include="Environment\OrchardStarterTests.cs" />
<Compile Include="Environment\ShellBuilders\DefaultShellContextFactoryTests.cs" />
<Compile Include="Environment\ShellBuilders\SetupShellContainerFactoryTests.cs" />
<Compile Include="Environment\TestDependencies\TestDependency.cs" />
<Compile Include="Environment\Topology\DefaultTopologyDescriptorCacheTests.cs" />

View File

@@ -1,3 +1,4 @@
using System;
using System.Linq;
using System.Web.Mvc;
using Autofac;
@@ -5,6 +6,8 @@ using Autofac.Integration.Web;
using System.Collections.Generic;
using Orchard.Environment.Configuration;
using Orchard.Environment.ShellBuilders;
using Orchard.Environment.Topology;
using Orchard.Environment.Topology.Models;
using Orchard.Extensions;
using Orchard.Mvc;
using Orchard.Mvc.ViewEngines;
@@ -22,6 +25,9 @@ namespace Orchard.Environment {
public DefaultOrchardHost(
IContainerProvider containerProvider,
ITenantManager tenantManager,
ITopologyDescriptorCache topologyDescriptorCache,
ICompositionStrategy compositionStrategy,
IShellContainerFactory shellContainerFactory,
ControllerBuilder controllerBuilder,
IEnumerable<IShellContainerFactory_Obsolete> shellContainerFactories) {
_containerProvider = containerProvider;
@@ -126,6 +132,7 @@ namespace Orchard.Environment {
finally {
containerProvider.EndRequestLifetime();
}
}
}
}
}
}

View File

@@ -0,0 +1,50 @@
using Autofac;
using Orchard.Environment.Configuration;
using Orchard.Environment.Topology;
using Orchard.Environment.Topology.Models;
namespace Orchard.Environment.ShellBuilders {
public class DefaultShellContextFactory : IShellContextFactory {
private readonly ITopologyDescriptorCache _topologyDescriptorCache;
private readonly ICompositionStrategy _compositionStrategy;
private readonly IShellContainerFactory _shellContainerFactory;
public DefaultShellContextFactory(
ITopologyDescriptorCache topologyDescriptorCache,
ICompositionStrategy compositionStrategy,
IShellContainerFactory shellContainerFactory) {
_topologyDescriptorCache = topologyDescriptorCache;
_compositionStrategy = compositionStrategy;
_shellContainerFactory = shellContainerFactory;
}
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<ITopologyDescriptorProvider>();
currentTopology = topologyDescriptorProvider.GetTopologyDescriptor();
}
if (cachedTopology.SerialNumber != currentTopology.SerialNumber) {
_topologyDescriptorCache.Store(settings.Name, currentTopology);
topology = _compositionStrategy.Compose(currentTopology);
shellScope = _shellContainerFactory.CreateContainer(topology);
}
var shell = shellScope.Resolve<IOrchardShell>();
return new ShellContext {
Settings = settings,
TopologyDescriptor = currentTopology,
Topology = topology,
LifetimeScope = shellScope,
Shell = shellScope.Resolve<IOrchardShell>(),
};
}
}
}

View File

@@ -0,0 +1,7 @@
using Orchard.Environment.Configuration;
namespace Orchard.Environment.ShellBuilders {
public interface IShellContextFactory {
ShellContext Create(ShellSettings settings);
}
}

View File

@@ -0,0 +1,13 @@
using Autofac;
using Orchard.Environment.Configuration;
using Orchard.Environment.Topology.Models;
namespace Orchard.Environment.ShellBuilders {
public class ShellContext {
public ShellSettings Settings { get; set; }
public ShellTopologyDescriptor TopologyDescriptor { get; set; }
public ShellTopology Topology { get; set; }
public ILifetimeScope LifetimeScope { get; set; }
public IOrchardShell Shell { get; set; }
}
}

View File

@@ -167,6 +167,9 @@
<Compile Include="Environment\Configuration\DefaultTenantManager.cs" />
<Compile Include="Environment\Configuration\ITenantManager.cs" />
<Compile Include="Environment\AutofacUtil\ContainerUpdater.cs" />
<Compile Include="Environment\ShellBuilders\DefaultShellContextFactory.cs" />
<Compile Include="Environment\ShellBuilders\IShellContextFactory.cs" />
<Compile Include="Environment\ShellBuilders\ShellContext.cs" />
<Compile Include="Environment\Topology\DefaultTopologyDescriptorCache.cs" />
<Compile Include="Environment\Topology\ICompositionStrategy.cs" />
<Compile Include="Environment\Topology\ITopologyDescriptorProvider.cs" />