diff --git a/src/Umbraco.Tests/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/PublishedCache/PublishedContentCacheTests.cs index ec2dbdb265..78a28145da 100644 --- a/src/Umbraco.Tests/PublishedCache/PublishedContentCacheTests.cs +++ b/src/Umbraco.Tests/PublishedCache/PublishedContentCacheTests.cs @@ -79,7 +79,7 @@ namespace Umbraco.Tests.PublishedCache var cache = new PublishedContentCache { - GetXmlDelegate = (user, preview) => + GetXmlDelegate = (context, preview) => { var doc = new XmlDocument(); doc.LoadXml(GetXml()); @@ -102,7 +102,7 @@ namespace Umbraco.Tests.PublishedCache var cache = _umbracoContext.ContentCache.InnerCache as PublishedContentCache; if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported."); - cache.GetXmlDelegate = (user, preview) => + cache.GetXmlDelegate = (context, preview) => { var doc = new XmlDocument(); doc.LoadXml(GetLegacyXml()); diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index c1cfcf2947..d6ef094169 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -286,7 +286,7 @@ namespace Umbraco.Tests.TestHelpers { var cache = new PublishedContentCache(); - cache.GetXmlDelegate = (user, preview) => + cache.GetXmlDelegate = (context, preview) => { var doc = new XmlDocument(); doc.LoadXml(GetXmlContent(templateId)); diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs index 15372a1758..88c8f3801e 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Runtime.CompilerServices; using System.Text; using System.Xml; using System.Xml.XPath; @@ -322,8 +323,10 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache #region Legacy Xml - private PreviewContent _previewContent; - private Func _xmlDelegate; + static readonly ConditionalWeakTable PreviewContentCache + = new ConditionalWeakTable(); + + private Func _xmlDelegate; /// /// Gets/sets the delegate used to retreive the Xml content, generally the setter is only used for unit tests @@ -334,22 +337,22 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache /// mostly because the 'content' object heavily relies on HttpContext, SQL connections and a bunch of other stuff /// that when run inside of a unit test fails. /// - internal Func GetXmlDelegate + internal Func GetXmlDelegate { get { - return _xmlDelegate ?? (_xmlDelegate = (user, preview) => + return _xmlDelegate ?? (_xmlDelegate = (context, preview) => { if (preview) { - if (_previewContent == null) + var previewContent = PreviewContentCache.GetOrCreateValue(context); // will use the ctor with no parameters + previewContent.EnsureInitialized(context.UmbracoUser, StateHelper.Cookies.Preview.GetValue(), true, () => { - _previewContent = new PreviewContent(user, new Guid(StateHelper.Cookies.Preview.GetValue()), true); - if (_previewContent.ValidPreviewSet) - _previewContent.LoadPreviewset(); - } - if (_previewContent.ValidPreviewSet) - return _previewContent.XmlContent; + if (previewContent.ValidPreviewSet) + previewContent.LoadPreviewset(); + }); + if (previewContent.ValidPreviewSet) + return previewContent.XmlContent; } return content.Instance.XmlContent; }); @@ -362,7 +365,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache internal XmlDocument GetXml(UmbracoContext umbracoContext, bool preview) { - return GetXmlDelegate(umbracoContext.UmbracoUser, preview); + return GetXmlDelegate(umbracoContext, preview); } #endregion diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/preview/PreviewContent.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/preview/PreviewContent.cs index 7b978a1c37..38dff3dfff 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/preview/PreviewContent.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/preview/PreviewContent.cs @@ -34,6 +34,27 @@ namespace umbraco.presentation.preview private int _userId = -1; + public PreviewContent() + { + _initialized = false; + } + + private readonly object _initLock = new object(); + private bool _initialized = true; + + public void EnsureInitialized(User user, string previewSet, bool validate, Action initialize) + { + lock (_initLock) + { + if (_initialized) return; + + _userId = user.Id; + ValidPreviewSet = UpdatePreviewPaths(new Guid(previewSet), validate); + initialize(); + _initialized = true; + } + } + public PreviewContent(User user) { _userId = user.Id;