mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 03:25:23 +08:00
Additional incremental work towards removing redundant layers.
--HG-- branch : dev
This commit is contained in:
@@ -44,7 +44,7 @@ namespace Orchard.Specs.Hosting.Orchard.Web {
|
||||
_host.ReloadExtensions();
|
||||
}
|
||||
|
||||
public static IStandaloneEnvironment CreateStandaloneEnvironment(string name) {
|
||||
public static IWorkContextScope CreateStandaloneEnvironment(string name) {
|
||||
var settings = _hostContainer.Resolve<IShellSettingsManager>().LoadSettings().SingleOrDefault(x => x.Name == name);
|
||||
return Host.CreateStandaloneEnvironment(settings);
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ namespace Orchard.Tests.Environment {
|
||||
var accessor = _container.Resolve<IWorkContextAccessor>();
|
||||
var httpContext = new StubHttpContext();
|
||||
|
||||
var workContextScope = accessor.CreateContextScope(httpContext);
|
||||
var workContextScope = accessor.CreateWorkContextScope(httpContext);
|
||||
Assert.That(workContextScope.WorkContext, Is.Not.Null);
|
||||
|
||||
var workContext = accessor.GetContext(httpContext);
|
||||
@@ -48,11 +48,11 @@ namespace Orchard.Tests.Environment {
|
||||
public void DifferentHttpContextWillHoldDifferentWorkContext() {
|
||||
var accessor = _container.Resolve<IWorkContextAccessor>();
|
||||
var httpContext1 = new StubHttpContext();
|
||||
var workContextScope1 = accessor.CreateContextScope(httpContext1);
|
||||
var workContextScope1 = accessor.CreateWorkContextScope(httpContext1);
|
||||
var workContext1 = accessor.GetContext(httpContext1);
|
||||
|
||||
var httpContext2 = new StubHttpContext();
|
||||
var workContextScope2 = accessor.CreateContextScope(httpContext2);
|
||||
var workContextScope2 = accessor.CreateWorkContextScope(httpContext2);
|
||||
var workContext2 = accessor.GetContext(httpContext2);
|
||||
|
||||
Assert.That(workContext1, Is.Not.Null);
|
||||
@@ -69,7 +69,7 @@ namespace Orchard.Tests.Environment {
|
||||
|
||||
Assert.That(accessor.GetContext(httpContext), Is.Null);
|
||||
|
||||
var scope = accessor.CreateContextScope(httpContext);
|
||||
var scope = accessor.CreateWorkContextScope(httpContext);
|
||||
Assert.That(accessor.GetContext(httpContext), Is.Not.Null);
|
||||
|
||||
scope.Dispose();
|
||||
@@ -89,11 +89,11 @@ namespace Orchard.Tests.Environment {
|
||||
Assert.That(accessor1.GetContext(httpContext), Is.Null);
|
||||
Assert.That(accessor2.GetContext(httpContext), Is.Null);
|
||||
|
||||
var scope1 = accessor1.CreateContextScope(httpContext);
|
||||
var scope1 = accessor1.CreateWorkContextScope(httpContext);
|
||||
Assert.That(accessor1.GetContext(httpContext), Is.Not.Null);
|
||||
Assert.That(accessor2.GetContext(httpContext), Is.Null);
|
||||
|
||||
var scope2 = accessor2.CreateContextScope(httpContext);
|
||||
var scope2 = accessor2.CreateWorkContextScope(httpContext);
|
||||
Assert.That(accessor1.GetContext(httpContext), Is.Not.Null);
|
||||
Assert.That(accessor2.GetContext(httpContext), Is.Not.Null);
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace Orchard.Tests.Environment {
|
||||
Assert.That(accessor.GetContext(ambientHttpContext), Is.Null);
|
||||
Assert.That(accessor.GetContext(explicitHttpContext), Is.Null);
|
||||
|
||||
var scope = accessor.CreateContextScope();
|
||||
var scope = accessor.CreateWorkContextScope();
|
||||
Assert.That(accessor.GetContext(), Is.Not.Null);
|
||||
Assert.That(accessor.GetContext(ambientHttpContext), Is.Not.Null);
|
||||
Assert.That(accessor.GetContext(explicitHttpContext), Is.Null);
|
||||
@@ -143,7 +143,7 @@ namespace Orchard.Tests.Environment {
|
||||
|
||||
Assert.That(accessor.GetContext(), Is.Null);
|
||||
|
||||
var scope = accessor.CreateContextScope();
|
||||
var scope = accessor.CreateWorkContextScope();
|
||||
Assert.That(accessor.GetContext(), Is.Not.Null);
|
||||
|
||||
scope.Dispose();
|
||||
@@ -161,11 +161,11 @@ namespace Orchard.Tests.Environment {
|
||||
Assert.That(accessor1.GetContext(), Is.Null);
|
||||
Assert.That(accessor2.GetContext(), Is.Null);
|
||||
|
||||
var scope1 = accessor1.CreateContextScope();
|
||||
var scope1 = accessor1.CreateWorkContextScope();
|
||||
Assert.That(accessor1.GetContext(), Is.Not.Null);
|
||||
Assert.That(accessor2.GetContext(), Is.Null);
|
||||
|
||||
var scope2 = accessor2.CreateContextScope();
|
||||
var scope2 = accessor2.CreateWorkContextScope();
|
||||
Assert.That(accessor1.GetContext(), Is.Not.Null);
|
||||
Assert.That(accessor2.GetContext(), Is.Not.Null);
|
||||
|
||||
|
@@ -112,7 +112,8 @@ namespace Orchard.Setup.Services {
|
||||
|
||||
// initialize database explicitly, and store shell descriptor
|
||||
var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellBlueprint);
|
||||
using ( var environment = new StandaloneEnvironment(bootstrapLifetimeScope) ) {
|
||||
|
||||
using (var environment = bootstrapLifetimeScope.CreateWorkContextScope()) {
|
||||
|
||||
// check if the database is already created (in case an exception occured in the second phase)
|
||||
var shellDescriptorRepository = environment.Resolve<IRepository<ShellDescriptorRecord>>();
|
||||
|
@@ -128,7 +128,7 @@ namespace Orchard.Commands {
|
||||
}
|
||||
|
||||
|
||||
private IStandaloneEnvironment CreateStandaloneEnvironment(string tenant) {
|
||||
private IWorkContextScope CreateStandaloneEnvironment(string tenant) {
|
||||
var host = _hostContainer.Resolve<IOrchardHost>();
|
||||
var tenantManager = _hostContainer.Resolve<IShellSettingsManager>();
|
||||
|
||||
|
@@ -28,24 +28,14 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
bool TryResolve(string key, Type serviceType, out object value) {
|
||||
// shared objects are resolved from the host first
|
||||
// this is to ensure the lifecycle of components registered at the host level
|
||||
// is consistent inside and outside of a containerproviderscope
|
||||
return
|
||||
TryResolveAtScope(_container, key, serviceType, out value) ||
|
||||
TryResolveAtScope(Scope.CurrentLifetimeScope, key, serviceType, out value);
|
||||
return TryResolveAtScope(_container, key, serviceType, out value) ;
|
||||
}
|
||||
|
||||
object CreateInstance(Type t) {
|
||||
static object CreateInstance(Type t) {
|
||||
if (t.IsAbstract || t.IsInterface)
|
||||
return null;
|
||||
|
||||
var instance = Activator.CreateInstance(t);
|
||||
if (instance is IContextualizable) {
|
||||
var effectiveContainer = Scope.CurrentLifetimeScope ?? _container;
|
||||
(instance as IContextualizable).Hook(() => effectiveContainer.InjectUnsetProperties(instance));
|
||||
}
|
||||
return instance;
|
||||
return Activator.CreateInstance(t);
|
||||
}
|
||||
|
||||
TService Resolve<TService>(Type serviceType, TService defaultValue = default(TService)) {
|
||||
@@ -111,53 +101,5 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
|
||||
public static IDisposable ContainerProviderScope(IContainerProvider containerProvider) {
|
||||
return new Scope(containerProvider);
|
||||
}
|
||||
|
||||
class Scope : IDisposable {
|
||||
private readonly IContainerProvider _containerProvider;
|
||||
readonly Scope _prior;
|
||||
|
||||
public Scope(IContainerProvider containerProvider) {
|
||||
_containerProvider = containerProvider;
|
||||
_prior = Current;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Current = _prior;
|
||||
}
|
||||
|
||||
public static ILifetimeScope CurrentLifetimeScope {
|
||||
get {
|
||||
var currentScope = Current;
|
||||
if (currentScope != null &&
|
||||
currentScope._containerProvider != null) {
|
||||
return currentScope._containerProvider.RequestLifetime;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[ThreadStatic]
|
||||
static Scope _fallback;
|
||||
static readonly object _contextKey = new object();
|
||||
|
||||
static Scope Current {
|
||||
get {
|
||||
var context = HttpContext.Current;
|
||||
return context != null ? (Scope)context.Items[_contextKey] : _fallback;
|
||||
}
|
||||
set {
|
||||
var context = HttpContext.Current;
|
||||
if (context != null)
|
||||
context.Items[_contextKey] = value;
|
||||
else {
|
||||
_fallback = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ using Orchard.Logging;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Mvc.ViewEngines;
|
||||
using Orchard.Utility.Extensions;
|
||||
using Autofac;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
public class DefaultOrchardHost : IOrchardHost, IShellSettingsManagerEventHandler, IShellDescriptorManagerEventHandler {
|
||||
@@ -77,13 +78,13 @@ namespace Orchard.Environment {
|
||||
EndRequest();
|
||||
}
|
||||
|
||||
IStandaloneEnvironment IOrchardHost.CreateStandaloneEnvironment(ShellSettings shellSettings) {
|
||||
IWorkContextScope IOrchardHost.CreateStandaloneEnvironment(ShellSettings shellSettings) {
|
||||
Logger.Debug("Creating standalone environment for tenant {0}", shellSettings.Name);
|
||||
|
||||
MonitorExtensions();
|
||||
BuildCurrent();
|
||||
var shellContext = CreateShellContext(shellSettings);
|
||||
return new StandaloneEnvironment(shellContext.LifetimeScope);
|
||||
return shellContext.LifetimeScope.CreateWorkContextScope();
|
||||
}
|
||||
|
||||
IEnumerable<ShellContext> BuildCurrent() {
|
||||
|
@@ -39,7 +39,7 @@ namespace Orchard.Environment {
|
||||
return _threadStaticContexts.TryGetValue(_workContextKey, out workContext) ? workContext : null;
|
||||
}
|
||||
|
||||
public IWorkContextScope CreateContextScope(HttpContextBase httpContext) {
|
||||
public IWorkContextScope CreateWorkContextScope(HttpContextBase httpContext) {
|
||||
|
||||
var workLifetime = SpawnWorkLifetime(builder => {
|
||||
builder.Register(ctx => httpContext)
|
||||
@@ -56,10 +56,10 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
|
||||
public IWorkContextScope CreateContextScope() {
|
||||
public IWorkContextScope CreateWorkContextScope() {
|
||||
var httpContext = _httpContextAccessor.Current();
|
||||
if (httpContext != null)
|
||||
return CreateContextScope(httpContext);
|
||||
return CreateWorkContextScope(httpContext);
|
||||
|
||||
var workLifetime = SpawnWorkLifetime(builder => {
|
||||
builder.Register(ctx => httpContext)
|
||||
@@ -116,6 +116,10 @@ namespace Orchard.Environment {
|
||||
public WorkContext WorkContext {
|
||||
get { return _workContext; }
|
||||
}
|
||||
|
||||
public TService Resolve<TService>() {
|
||||
return WorkContext.Service<TService>();
|
||||
}
|
||||
}
|
||||
|
||||
class ThreadStaticScopeImplementation : IWorkContextScope {
|
||||
@@ -139,6 +143,10 @@ namespace Orchard.Environment {
|
||||
public WorkContext WorkContext {
|
||||
get { return _workContext; }
|
||||
}
|
||||
|
||||
public TService Resolve<TService>() {
|
||||
return WorkContext.Service<TService>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,25 +0,0 @@
|
||||
using Autofac;
|
||||
using Autofac.Integration.Web;
|
||||
using Orchard.Environment.AutofacUtil;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
|
||||
class FiniteContainerProvider : IContainerProvider {
|
||||
public FiniteContainerProvider(ILifetimeScope applicationContainer) {
|
||||
ApplicationContainer = new LifetimeScopeContainer(applicationContainer);
|
||||
RequestLifetime = ApplicationContainer.BeginLifetimeScope("httpRequest");
|
||||
}
|
||||
|
||||
public void EndRequestLifetime() {
|
||||
var disposeContainer = RequestLifetime;
|
||||
RequestLifetime = null;
|
||||
|
||||
if (disposeContainer != null)
|
||||
disposeContainer.Dispose();
|
||||
}
|
||||
|
||||
public IContainer ApplicationContainer { get; private set; }
|
||||
|
||||
public ILifetimeScope RequestLifetime { get; private set; }
|
||||
}
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
public interface IContextualizable {
|
||||
void Hook(params Action[] contextualizers);
|
||||
}
|
||||
}
|
@@ -28,6 +28,6 @@ namespace Orchard.Environment {
|
||||
/// Can be used to build an temporary self-contained instance of a shell's configured code.
|
||||
/// Services may be resolved from within this instance to configure and initialize it's storage.
|
||||
/// </summary>
|
||||
IStandaloneEnvironment CreateStandaloneEnvironment(ShellSettings shellSettings);
|
||||
IWorkContextScope CreateStandaloneEnvironment(ShellSettings shellSettings);
|
||||
}
|
||||
}
|
||||
|
@@ -61,7 +61,7 @@ namespace Orchard.Environment.ShellBuilders {
|
||||
var shellScope = _shellContainerFactory.CreateContainer(settings, blueprint);
|
||||
|
||||
ShellDescriptor currentDescriptor;
|
||||
using (var standaloneEnvironment = new StandaloneEnvironment(shellScope)) {
|
||||
using (var standaloneEnvironment = shellScope.CreateWorkContextScope()) {
|
||||
var shellDescriptorManager = standaloneEnvironment.Resolve<IShellDescriptorManager>();
|
||||
currentDescriptor = shellDescriptorManager.GetShellDescriptor();
|
||||
}
|
||||
|
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using Autofac;
|
||||
using Autofac.Integration.Web;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
public interface IStandaloneEnvironment : IDisposable {
|
||||
TService Resolve<TService>();
|
||||
}
|
||||
|
||||
public class StandaloneEnvironment : IStandaloneEnvironment {
|
||||
private readonly IContainerProvider _containerProvider;
|
||||
|
||||
public StandaloneEnvironment(ILifetimeScope applicationContainer) {
|
||||
_containerProvider = new FiniteContainerProvider(applicationContainer);
|
||||
}
|
||||
|
||||
public TService Resolve<TService>() {
|
||||
return _containerProvider.RequestLifetime.Resolve<TService>();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
_containerProvider.EndRequestLifetime();
|
||||
}
|
||||
}
|
||||
}
|
@@ -68,7 +68,7 @@ namespace Orchard.Environment.State {
|
||||
private void Execute(Entry entry) {
|
||||
var shellContext = _shellContextFactory.CreateDescribedContext(entry.ShellSettings, entry.ShellDescriptor);
|
||||
using (shellContext.LifetimeScope) {
|
||||
using (var standaloneEnvironment = new StandaloneEnvironment(shellContext.LifetimeScope)) {
|
||||
using (var standaloneEnvironment = shellContext.LifetimeScope.CreateWorkContextScope()) {
|
||||
var eventBus = standaloneEnvironment.Resolve<IEventBus>();
|
||||
|
||||
Logger.Information("Executing event {0} in process {1} for shell {2}",
|
||||
|
@@ -4,13 +4,14 @@ using System.Web;
|
||||
namespace Orchard {
|
||||
public interface IWorkContextAccessor : ISingletonDependency {
|
||||
WorkContext GetContext(HttpContextBase httpContext);
|
||||
IWorkContextScope CreateContextScope(HttpContextBase httpContext);
|
||||
IWorkContextScope CreateWorkContextScope(HttpContextBase httpContext);
|
||||
|
||||
WorkContext GetContext();
|
||||
IWorkContextScope CreateContextScope();
|
||||
IWorkContextScope CreateWorkContextScope();
|
||||
}
|
||||
|
||||
public interface IWorkContextScope : IDisposable {
|
||||
WorkContext WorkContext { get; }
|
||||
TService Resolve<TService>();
|
||||
}
|
||||
}
|
||||
|
@@ -5,8 +5,8 @@ using Orchard.Mvc;
|
||||
namespace Orchard.Localization {
|
||||
public class LocalizationUtilities {
|
||||
public static Localizer Resolve(ControllerContext controllerContext, string scope) {
|
||||
var context = OrchardControllerFactory.GetRequestContainer(controllerContext.RouteData);
|
||||
return context == null ? NullLocalizer.Instance : Resolve(context, scope);
|
||||
var context = controllerContext.GetWorkContext();
|
||||
return context == null ? NullLocalizer.Instance : Resolve(context.Service<ILifetimeScope>(), scope);
|
||||
}
|
||||
|
||||
public static Localizer Resolve(IComponentContext context, string scope) {
|
||||
|
@@ -11,11 +11,15 @@ namespace Orchard.Mvc.Html {
|
||||
/// <see cref="http://en.wikipedia.org/wiki/Harry_Houdini"/>
|
||||
/// <returns>himself</returns>
|
||||
public static TService Resolve<TService>(this HtmlHelper html) {
|
||||
var containerProvider = html.ViewContext.RouteData.DataTokens["IContainerProvider"] as IContainerProvider;
|
||||
if (containerProvider == null)
|
||||
var workContextAccessor = html.ViewContext.RouteData.DataTokens["IWorkContextAccessor"] as IWorkContextAccessor;
|
||||
if (workContextAccessor == null)
|
||||
throw new ApplicationException("Unable to resolve");
|
||||
|
||||
return (containerProvider.RequestLifetime).Resolve<TService>();
|
||||
var workContext = workContextAccessor.GetContext(html.ViewContext.HttpContext);
|
||||
if (workContext == null)
|
||||
throw new ApplicationException("Unable to resolve");
|
||||
|
||||
return workContext.Service<TService>();
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ using Autofac.Integration.Web;
|
||||
|
||||
namespace Orchard.Mvc {
|
||||
public class OrchardControllerFactory : DefaultControllerFactory {
|
||||
|
||||
|
||||
public override IController CreateController(RequestContext requestContext, string controllerName) {
|
||||
var routeData = requestContext.RouteData;
|
||||
|
||||
@@ -19,12 +19,14 @@ namespace Orchard.Mvc {
|
||||
// Now that the request container is known - try to resolve the controller
|
||||
object controller;
|
||||
var service = new KeyedService(serviceKey, typeof(IController));
|
||||
|
||||
// Locate the container this route is bound against
|
||||
var container = GetRequestContainer(routeData);
|
||||
|
||||
if (container != null &&
|
||||
container.TryResolve(service, out controller)) {
|
||||
// Locate the container this route is bound against
|
||||
var workContextAccessor = GetWorkContextAccessor(routeData);
|
||||
|
||||
var workContext = workContextAccessor != null ? workContextAccessor.GetContext(requestContext.HttpContext) : null;
|
||||
|
||||
if (workContext != null &&
|
||||
workContext.Service<ILifetimeScope>().TryResolve(service, out controller)) {
|
||||
return (IController)controller;
|
||||
}
|
||||
|
||||
@@ -54,14 +56,13 @@ namespace Orchard.Mvc {
|
||||
return GetAreaName(routeData.Route);
|
||||
}
|
||||
|
||||
public static ILifetimeScope GetRequestContainer(RouteData routeData) {
|
||||
static IWorkContextAccessor GetWorkContextAccessor(RouteData routeData) {
|
||||
object dataTokenValue;
|
||||
if (routeData != null &&
|
||||
routeData.DataTokens != null &&
|
||||
routeData.DataTokens.TryGetValue("IContainerProvider", out dataTokenValue) &&
|
||||
dataTokenValue is IContainerProvider) {
|
||||
var containerProvider = (IContainerProvider) dataTokenValue;
|
||||
return containerProvider.RequestLifetime;
|
||||
routeData.DataTokens.TryGetValue("IWorkContextAccessor", out dataTokenValue) &&
|
||||
dataTokenValue is IWorkContextAccessor) {
|
||||
return (IWorkContextAccessor)dataTokenValue;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@@ -14,15 +14,15 @@ namespace Orchard.Mvc.Routes {
|
||||
public class ShellRoute : RouteBase, IRouteWithArea {
|
||||
private readonly RouteBase _route;
|
||||
private readonly ShellSettings _shellSettings;
|
||||
private readonly IContainer _container;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IRunningShellTable _runningShellTable;
|
||||
private UrlPrefix _urlPrefix;
|
||||
private readonly UrlPrefix _urlPrefix;
|
||||
|
||||
public ShellRoute(RouteBase route, ShellSettings shellSettings, ILifetimeScope shellLifetimeScope, IRunningShellTable runningShellTable) {
|
||||
_route = route;
|
||||
_shellSettings = shellSettings;
|
||||
_runningShellTable = runningShellTable;
|
||||
_container = new LifetimeScopeContainer(shellLifetimeScope);
|
||||
_workContextAccessor = shellLifetimeScope.Resolve<IWorkContextAccessor>();
|
||||
if (!string.IsNullOrEmpty(_shellSettings.RequestUrlPrefix))
|
||||
_urlPrefix = new UrlPrefix(_shellSettings.RequestUrlPrefix);
|
||||
|
||||
@@ -56,10 +56,9 @@ namespace Orchard.Mvc.Routes {
|
||||
if (routeData == null)
|
||||
return null;
|
||||
|
||||
// otherwise paint wrap handler and return it
|
||||
var containerProvider = new ContainerProvider(_container);
|
||||
routeData.RouteHandler = new RouteHandler(containerProvider, routeData.RouteHandler);
|
||||
routeData.DataTokens["IContainerProvider"] = containerProvider;
|
||||
// otherwise wrap handler and return it
|
||||
routeData.RouteHandler = new RouteHandler(_workContextAccessor, routeData.RouteHandler);
|
||||
routeData.DataTokens["IWorkContextAccessor"] = _workContextAccessor;
|
||||
return routeData;
|
||||
}
|
||||
|
||||
@@ -86,48 +85,30 @@ namespace Orchard.Mvc.Routes {
|
||||
return virtualPath;
|
||||
}
|
||||
|
||||
class ContainerProvider : IContainerProvider {
|
||||
public ContainerProvider(IContainer applicationContainer) {
|
||||
ApplicationContainer = applicationContainer;
|
||||
}
|
||||
|
||||
public void BeginRequestLifetime() {
|
||||
RequestLifetime = ApplicationContainer.BeginLifetimeScope("httpRequest");
|
||||
}
|
||||
|
||||
public void EndRequestLifetime() {
|
||||
RequestLifetime.Dispose();
|
||||
RequestLifetime = null;
|
||||
}
|
||||
|
||||
public IContainer ApplicationContainer { get; set; }
|
||||
public ILifetimeScope RequestLifetime { get; set; }
|
||||
}
|
||||
|
||||
class RouteHandler : IRouteHandler {
|
||||
private readonly ContainerProvider _containerProvider;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IRouteHandler _routeHandler;
|
||||
|
||||
public RouteHandler(ContainerProvider containerProvider, IRouteHandler routeHandler) {
|
||||
_containerProvider = containerProvider;
|
||||
public RouteHandler(IWorkContextAccessor workContextAccessor, IRouteHandler routeHandler) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_routeHandler = routeHandler;
|
||||
}
|
||||
|
||||
public IHttpHandler GetHttpHandler(RequestContext requestContext) {
|
||||
var httpHandler = _routeHandler.GetHttpHandler(requestContext);
|
||||
if (httpHandler is IHttpAsyncHandler) {
|
||||
return new HttpAsyncHandler(_containerProvider, (IHttpAsyncHandler)httpHandler);
|
||||
return new HttpAsyncHandler(_workContextAccessor, (IHttpAsyncHandler)httpHandler);
|
||||
}
|
||||
return new HttpHandler(_containerProvider, httpHandler);
|
||||
return new HttpHandler(_workContextAccessor, httpHandler);
|
||||
}
|
||||
}
|
||||
|
||||
class HttpHandler : IHttpHandler, IRequiresSessionState, IHasRequestContext {
|
||||
protected readonly ContainerProvider _containerProvider;
|
||||
protected readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IHttpHandler _httpHandler;
|
||||
|
||||
public HttpHandler(ContainerProvider containerProvider, IHttpHandler httpHandler) {
|
||||
_containerProvider = containerProvider;
|
||||
public HttpHandler(IWorkContextAccessor workContextAccessor, IHttpHandler httpHandler) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_httpHandler = httpHandler;
|
||||
}
|
||||
|
||||
@@ -136,14 +117,8 @@ namespace Orchard.Mvc.Routes {
|
||||
}
|
||||
|
||||
public void ProcessRequest(HttpContext context) {
|
||||
using (DefaultOrchardHostContainer.ContainerProviderScope(_containerProvider)) {
|
||||
_containerProvider.BeginRequestLifetime();
|
||||
try {
|
||||
_httpHandler.ProcessRequest(context);
|
||||
}
|
||||
finally {
|
||||
_containerProvider.EndRequestLifetime();
|
||||
}
|
||||
using (_workContextAccessor.CreateWorkContextScope(new HttpContextWrapper(context))) {
|
||||
_httpHandler.ProcessRequest(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,19 +134,17 @@ namespace Orchard.Mvc.Routes {
|
||||
private readonly IHttpAsyncHandler _httpAsyncHandler;
|
||||
private IDisposable _scope;
|
||||
|
||||
public HttpAsyncHandler(ContainerProvider containerProvider, IHttpAsyncHandler httpAsyncHandler)
|
||||
public HttpAsyncHandler(IWorkContextAccessor containerProvider, IHttpAsyncHandler httpAsyncHandler)
|
||||
: base(containerProvider, httpAsyncHandler) {
|
||||
_httpAsyncHandler = httpAsyncHandler;
|
||||
}
|
||||
|
||||
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
|
||||
_scope = DefaultOrchardHostContainer.ContainerProviderScope(_containerProvider);
|
||||
_containerProvider.BeginRequestLifetime();
|
||||
_scope = _workContextAccessor.CreateWorkContextScope(new HttpContextWrapper(context));
|
||||
try {
|
||||
return _httpAsyncHandler.BeginProcessRequest(context, cb, extraData);
|
||||
}
|
||||
catch {
|
||||
_containerProvider.EndRequestLifetime();
|
||||
_scope.Dispose();
|
||||
throw;
|
||||
}
|
||||
@@ -182,7 +155,6 @@ namespace Orchard.Mvc.Routes {
|
||||
_httpAsyncHandler.EndProcessRequest(result);
|
||||
}
|
||||
finally {
|
||||
_containerProvider.EndRequestLifetime();
|
||||
_scope.Dispose();
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ using Orchard.Security.Permissions;
|
||||
|
||||
namespace Orchard.Mvc.ViewEngines.Razor {
|
||||
|
||||
public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>, IContextualizable {
|
||||
public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel> {
|
||||
private object _display;
|
||||
private Localizer _localizer = NullLocalizer.Instance;
|
||||
private IEnumerable<Action> _contexturalizers = Enumerable.Empty<Action>();
|
||||
@@ -31,8 +31,8 @@ namespace Orchard.Mvc.ViewEngines.Razor {
|
||||
public override void InitHelpers() {
|
||||
base.InitHelpers();
|
||||
|
||||
foreach (var contextualize in _contexturalizers)
|
||||
contextualize();
|
||||
var workContext = ViewContext.GetWorkContext();
|
||||
workContext.Service<IContainer>().InjectUnsetProperties(this);
|
||||
|
||||
_localizer = LocalizationUtilities.Resolve(ViewContext, VirtualPath);
|
||||
_display = DisplayHelperFactory.CreateHelper(ViewContext, this);
|
||||
@@ -43,11 +43,6 @@ namespace Orchard.Mvc.ViewEngines.Razor {
|
||||
return Authorizer.Authorize(permission);
|
||||
}
|
||||
|
||||
void IContextualizable.Hook(params Action[] contextualizers) {
|
||||
if (contextualizers != null && contextualizers.Any()) {
|
||||
_contexturalizers = (_contexturalizers.Any()) ? _contexturalizers.Concat(contextualizers) : contextualizers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class WebViewPage : WebViewPage<object> {
|
||||
|
@@ -403,7 +403,6 @@
|
||||
<Compile Include="DisplayManagement\Implementation\ShapeHelper.cs" />
|
||||
<Compile Include="DisplayManagement\Implementation\ShapeHelperFactory.cs" />
|
||||
<Compile Include="Environment\DefaultWorkContextAccessor.cs" />
|
||||
<Compile Include="Environment\IContextualizable.cs" />
|
||||
<Compile Include="Environment\IHostLocalRestart.cs" />
|
||||
<Compile Include="Environment\IShellContainerRegistrations.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\DynamicModuleVirtualPathProvider.cs" />
|
||||
@@ -613,7 +612,6 @@
|
||||
<Compile Include="Environment\Descriptor\Models\ShellDescriptor.cs" />
|
||||
<Compile Include="Environment\ShellBuilders\ShellContainerFactory.cs" />
|
||||
<Compile Include="Environment\Configuration\ShellSettings.cs" />
|
||||
<Compile Include="Environment\StandaloneEnvironment.cs" />
|
||||
<Compile Include="Events\DefaultOrchardEventBus.cs" />
|
||||
<Compile Include="Events\EventsInterceptor.cs" />
|
||||
<Compile Include="Events\EventsModule.cs" />
|
||||
@@ -673,7 +671,6 @@
|
||||
<Compile Include="Mvc\Html\FileRegistrationContext.cs" />
|
||||
<Compile Include="Mvc\Html\MvcFormAntiForgeryPost.cs" />
|
||||
<Compile Include="Mvc\Html\SiteServiceExtensions.cs" />
|
||||
<Compile Include="Environment\FiniteContainerProvider.cs" />
|
||||
<Compile Include="Tasks\Scheduling\IScheduledTaskHandler.cs" />
|
||||
<Compile Include="Tasks\Scheduling\IScheduledTaskManager.cs" />
|
||||
<Compile Include="Tasks\Scheduling\ScheduledTaskContext.cs" />
|
||||
|
@@ -56,7 +56,7 @@ namespace Orchard.Tasks {
|
||||
|
||||
public void DoWork() {
|
||||
// makes an inner container, similar to the per-request container
|
||||
using (var standaloneEnvironment = new StandaloneEnvironment(_container)) {
|
||||
using (var standaloneEnvironment = _container.CreateWorkContextScope()) {
|
||||
// resolve the manager and invoke it
|
||||
var manager = standaloneEnvironment.Resolve<IBackgroundService>();
|
||||
manager.Sweep();
|
||||
|
@@ -1,9 +1,45 @@
|
||||
using System.Web.Mvc;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Autofac;
|
||||
|
||||
namespace Orchard {
|
||||
public static class WorkContextExtensions {
|
||||
public static WorkContext GetContext(this IWorkContextAccessor workContextAccessor, ControllerContext controllerContext) {
|
||||
return workContextAccessor.GetContext(controllerContext.RequestContext.HttpContext);
|
||||
}
|
||||
|
||||
public static WorkContext GetWorkContext(this RequestContext requestContext) {
|
||||
if (requestContext == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var routeData = requestContext.RouteData;
|
||||
object value;
|
||||
if (routeData == null ||
|
||||
routeData.DataTokens == null ||
|
||||
!routeData.DataTokens.TryGetValue("IWorkContextAccessor", out value) ||
|
||||
!(value is IWorkContextAccessor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var workContextAccessor = (IWorkContextAccessor)value;
|
||||
return workContextAccessor.GetContext(requestContext.HttpContext);
|
||||
}
|
||||
|
||||
public static WorkContext GetWorkContext(this ControllerContext controllerContext) {
|
||||
if (controllerContext == null) {
|
||||
return null;
|
||||
}
|
||||
return WorkContextExtensions.GetWorkContext(controllerContext.RequestContext);
|
||||
}
|
||||
|
||||
public static IWorkContextScope CreateWorkContextScope(this ILifetimeScope lifetimeScope, HttpContextBase httpContext) {
|
||||
return lifetimeScope.Resolve<IWorkContextAccessor>().CreateWorkContextScope(httpContext);
|
||||
}
|
||||
|
||||
public static IWorkContextScope CreateWorkContextScope(this ILifetimeScope lifetimeScope) {
|
||||
return lifetimeScope.Resolve<IWorkContextAccessor>().CreateWorkContextScope();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user