From ec6899344893da1aa5dc0dfa4c6357f5d6907682 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 20 Oct 2016 10:52:11 +0200 Subject: [PATCH] Cleanup hybrid accessors --- src/Umbraco.Web/HybridAccessorBase.cs | 37 +++++++++---------- .../HybridEventMessagesAccessor.cs | 9 +---- .../HybridUmbracoContextAccessor.cs | 11 +----- .../HybridUmbracoDatabaseAccessor.cs | 9 +---- 4 files changed, 22 insertions(+), 44 deletions(-) diff --git a/src/Umbraco.Web/HybridAccessorBase.cs b/src/Umbraco.Web/HybridAccessorBase.cs index be62a9dfff..a14caa60a2 100644 --- a/src/Umbraco.Web/HybridAccessorBase.cs +++ b/src/Umbraco.Web/HybridAccessorBase.cs @@ -7,6 +7,11 @@ namespace Umbraco.Web internal abstract class HybridAccessorBase where T : class { + // ReSharper disable StaticMemberInGenericType + private static readonly object Locker = new object(); + private static bool _registered; + // ReSharper restore StaticMemberInGenericType + private readonly IHttpContextAccessor _httpContextAccessor; protected abstract string ItemKey { get; } @@ -20,11 +25,6 @@ namespace Umbraco.Web // // anything that is ThreadStatic will stay with the thread and NOT flow in async threads // the only thing that flows is the logical call context (safe in 4.5+) - // now... - // fixme - which tests?! - // tests seem to show that either newing Thread or enqueuing in the ThreadPool both produce a thread - // with a clear logical call context, which would mean that it is somewhat safe to "fire and forget" - // because whatever is in the call context will be gone when the thread returns to the pool // no! //[ThreadStatic] @@ -41,16 +41,20 @@ namespace Umbraco.Web } } - // every class inheriting from this class *must* implement a static ctor - // and register itself against the SafeCallContext using this method. - // - // note: because the item key is not static, we cannot register here in the - // base class - unless we do it in the non-static Value property setter, - // with a static bool to keep track of registration - less error-prone but - // perfs impact - considering implementors should be careful. - // - protected static void SafeCallContextRegister(string itemKey) + protected HybridAccessorBase(IHttpContextAccessor httpContextAccessor) { + if (httpContextAccessor == null) throw new ArgumentNullException(nameof(httpContextAccessor)); + _httpContextAccessor = httpContextAccessor; + + lock (Locker) + { + // register the itemKey once with SafeCallContext + if (_registered) return; + _registered = true; + } + + // ReSharper disable once VirtualMemberCallInConstructor + var itemKey = ItemKey; // virtual SafeCallContext.Register(() => { var value = CallContext.LogicalGetData(itemKey); @@ -65,11 +69,6 @@ namespace Umbraco.Web }); } - protected HybridAccessorBase(IHttpContextAccessor httpContextAccessor) - { - _httpContextAccessor = httpContextAccessor; - } - protected T Value { get diff --git a/src/Umbraco.Web/HybridEventMessagesAccessor.cs b/src/Umbraco.Web/HybridEventMessagesAccessor.cs index 6c0b848736..fddde403d8 100644 --- a/src/Umbraco.Web/HybridEventMessagesAccessor.cs +++ b/src/Umbraco.Web/HybridEventMessagesAccessor.cs @@ -4,14 +4,7 @@ namespace Umbraco.Web { internal class HybridEventMessagesAccessor : HybridAccessorBase, IEventMessagesAccessor { - private const string ItemKeyConst = "Umbraco.Core.Events.HybridEventMessagesAccessor"; - - protected override string ItemKey => ItemKeyConst; - - static HybridEventMessagesAccessor() - { - SafeCallContextRegister(ItemKeyConst); - } + protected override string ItemKey => "Umbraco.Core.Events.HybridEventMessagesAccessor"; public HybridEventMessagesAccessor(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor) diff --git a/src/Umbraco.Web/HybridUmbracoContextAccessor.cs b/src/Umbraco.Web/HybridUmbracoContextAccessor.cs index a3edeb9f05..e8a07b0f4c 100644 --- a/src/Umbraco.Web/HybridUmbracoContextAccessor.cs +++ b/src/Umbraco.Web/HybridUmbracoContextAccessor.cs @@ -2,19 +2,12 @@ { internal class HybridUmbracoContextAccessor : HybridAccessorBase, IUmbracoContextAccessor { - private const string ItemKeyConst = "Umbraco.Web.HybridUmbracoContextAccessor"; - - protected override string ItemKey => ItemKeyConst; - - static HybridUmbracoContextAccessor() - { - SafeCallContextRegister(ItemKeyConst); - } - public HybridUmbracoContextAccessor(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor) { } + protected override string ItemKey => "Umbraco.Web.HybridUmbracoContextAccessor"; + public UmbracoContext UmbracoContext { get { return Value; } diff --git a/src/Umbraco.Web/HybridUmbracoDatabaseAccessor.cs b/src/Umbraco.Web/HybridUmbracoDatabaseAccessor.cs index 735df8d8ce..b137df9a7a 100644 --- a/src/Umbraco.Web/HybridUmbracoDatabaseAccessor.cs +++ b/src/Umbraco.Web/HybridUmbracoDatabaseAccessor.cs @@ -4,14 +4,7 @@ namespace Umbraco.Web { internal class HybridUmbracoDatabaseAccessor : HybridAccessorBase, IUmbracoDatabaseAccessor { - private const string ItemKeyConst = "Umbraco.Core.Persistence.HybridUmbracoDatabaseAccessor"; - - protected override string ItemKey => ItemKeyConst; - - static HybridUmbracoDatabaseAccessor() - { - SafeCallContextRegister(ItemKeyConst); - } + protected override string ItemKey => "Umbraco.Core.Persistence.HybridUmbracoDatabaseAccessor"; public HybridUmbracoDatabaseAccessor(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)