diff --git a/src/Umbraco.Core/Services/ServiceContext.cs b/src/Umbraco.Core/Services/ServiceContext.cs index a18df0ade1..f2969de3be 100644 --- a/src/Umbraco.Core/Services/ServiceContext.cs +++ b/src/Umbraco.Core/Services/ServiceContext.cs @@ -176,6 +176,8 @@ namespace Umbraco.Core.Services if (logger == null) throw new ArgumentNullException("logger"); if (eventMessagesFactory == null) throw new ArgumentNullException("eventMessagesFactory"); + EventMessagesFactory = eventMessagesFactory; + BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, publishingStrategy, cache, repositoryFactory, logger, eventMessagesFactory); @@ -193,6 +195,8 @@ namespace Umbraco.Core.Services ILogger logger, IEventMessagesFactory eventMessagesFactory) { + EventMessagesFactory = eventMessagesFactory; + var provider = dbUnitOfWorkProvider; var fileProvider = fileUnitOfWorkProvider; @@ -316,6 +320,8 @@ namespace Umbraco.Core.Services _redirectUrlService = new Lazy(() => new RedirectUrlService(provider, repositoryFactory, logger, eventMessagesFactory)); } + internal IEventMessagesFactory EventMessagesFactory { get; private set; } + /// /// Gets the /// diff --git a/src/Umbraco.Web/RequestLifespanMessagesFactory.cs b/src/Umbraco.Web/RequestLifespanMessagesFactory.cs index 26ac3bd5df..cf75e60755 100644 --- a/src/Umbraco.Web/RequestLifespanMessagesFactory.cs +++ b/src/Umbraco.Web/RequestLifespanMessagesFactory.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.Remoting.Messaging; using Umbraco.Core.Events; namespace Umbraco.Web @@ -8,6 +9,7 @@ namespace Umbraco.Web /// internal class RequestLifespanMessagesFactory : IEventMessagesFactory { + private const string ContextKey = "Umbraco.Web.RequestLifespanMessagesFactory"; private readonly IHttpContextAccessor _httpAccessor; public RequestLifespanMessagesFactory(IHttpContextAccessor httpAccessor) @@ -18,11 +20,43 @@ namespace Umbraco.Web public EventMessages Get() { - if (_httpAccessor.Value.Items[typeof (RequestLifespanMessagesFactory).Name] == null) + var httpContext = _httpAccessor.Value; + if (httpContext != null) { - _httpAccessor.Value.Items[typeof(RequestLifespanMessagesFactory).Name] = new EventMessages(); + var eventMessages = httpContext.Items[ContextKey] as EventMessages; + if (eventMessages == null) httpContext.Items[ContextKey] = eventMessages = new EventMessages(); + return eventMessages; } - return (EventMessages)_httpAccessor.Value.Items[typeof (RequestLifespanMessagesFactory).Name]; + + var lccContext = CallContext.LogicalGetData(ContextKey) as EventMessages; + if (lccContext != null) return lccContext; + + throw new Exception("Could not get messages."); + } + + public EventMessages TryGet() + { + var httpContext = _httpAccessor.Value; + return httpContext != null + ? httpContext.Items[ContextKey] as EventMessages + : CallContext.LogicalGetData(ContextKey) as EventMessages; + } + + // Deploy wants to execute things outside of a request, where this factory would fail, + // so the factory is extended so that Deploy can Set/Clear event messages in the logical + // call context (which flows with async) - it needs to be set and cleared because, contrary + // to http context, it's not being cleared at the end of anything. + // + // to be refactored in v8! the whole IEventMessagesFactory is borked anyways + + public void SetLlc() + { + CallContext.LogicalSetData(ContextKey, new EventMessages()); + } + + public void ClearLlc() + { + CallContext.FreeNamedDataSlot(ContextKey); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/SingletonHttpContextAccessor.cs b/src/Umbraco.Web/SingletonHttpContextAccessor.cs index cdeafa48e1..3d6ac159fb 100644 --- a/src/Umbraco.Web/SingletonHttpContextAccessor.cs +++ b/src/Umbraco.Web/SingletonHttpContextAccessor.cs @@ -6,7 +6,11 @@ namespace Umbraco.Web { public HttpContextBase Value { - get { return new HttpContextWrapper(HttpContext.Current); } + get + { + var httpContext = HttpContext.Current; + return httpContext == null ? null : new HttpContextWrapper(httpContext); + } } } } \ No newline at end of file diff --git a/src/Umbraco.Web/UmbracoContextExtensions.cs b/src/Umbraco.Web/UmbracoContextExtensions.cs index 8cd38df6d1..53ef92690e 100644 --- a/src/Umbraco.Web/UmbracoContextExtensions.cs +++ b/src/Umbraco.Web/UmbracoContextExtensions.cs @@ -53,9 +53,8 @@ namespace Umbraco.Web /// public static EventMessages GetCurrentEventMessages(this UmbracoContext umbracoContext) { - var msgs = umbracoContext.HttpContext.Items[typeof (RequestLifespanMessagesFactory).Name]; - if (msgs == null) return null; - return (EventMessages) msgs; + var eventMessagesFactory = umbracoContext.Application.Services.EventMessagesFactory as RequestLifespanMessagesFactory; + return eventMessagesFactory == null ? null : eventMessagesFactory.TryGet(); } }