diff --git a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs index e7352b999..ed898f7f2 100644 --- a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs +++ b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs @@ -128,8 +128,7 @@ Features: Assert.Throws(typeof(InvalidOperationException), () => themeRecipeHandler.ExecuteRecipeStep(recipeContext)); } - internal class StubSiteThemeService : ISiteThemeService - { + internal class StubSiteThemeService : ISiteThemeService { public ExtensionDescriptor GetSiteTheme() { throw new NotImplementedException(); } @@ -137,6 +136,10 @@ Features: public void SetSiteTheme(string themeName) { throw new NotImplementedException(); } + + public string GetCurrentThemeName() { + throw new NotImplementedException(); + } } } } diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Services/SiteThemeSelector.cs b/src/Orchard.Web/Modules/Orchard.Themes/Services/SiteThemeSelector.cs index 3b3369e87..518afdac1 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Services/SiteThemeSelector.cs +++ b/src/Orchard.Web/Modules/Orchard.Themes/Services/SiteThemeSelector.cs @@ -1,23 +1,19 @@ using System; using System.Web.Routing; using JetBrains.Annotations; -using Orchard.ContentManagement; -using Orchard.Themes.Models; namespace Orchard.Themes.Services { [UsedImplicitly] public class SiteThemeSelector : IThemeSelector { - private readonly IOrchardServices _orchardServices; + private readonly ISiteThemeService _siteThemeService; - public SiteThemeSelector(IOrchardServices orchardServices) { - _orchardServices = orchardServices; + public SiteThemeSelector(ISiteThemeService siteThemeService) { + _siteThemeService = siteThemeService; } public ThemeSelectorResult GetTheme(RequestContext context) { - string currentThemeName = _orchardServices.WorkContext.CurrentSite.As().Record.CurrentThemeName; - + string currentThemeName = _siteThemeService.GetCurrentThemeName(); return String.IsNullOrEmpty(currentThemeName) ? null : new ThemeSelectorResult { Priority = -5, ThemeName = currentThemeName }; } } - } diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Services/SiteThemeService.cs b/src/Orchard.Web/Modules/Orchard.Themes/Services/SiteThemeService.cs index 877db83a0..7a1c10902 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Services/SiteThemeService.cs +++ b/src/Orchard.Web/Modules/Orchard.Themes/Services/SiteThemeService.cs @@ -1,4 +1,5 @@ -using Orchard.ContentManagement; +using Orchard.Caching; +using Orchard.ContentManagement; using Orchard.Environment.Extensions; using Orchard.Environment.Extensions.Models; using Orchard.Localization; @@ -9,31 +10,55 @@ namespace Orchard.Themes.Services { public interface ISiteThemeService : IDependency { ExtensionDescriptor GetSiteTheme(); void SetSiteTheme(string themeName); + string GetCurrentThemeName(); } public class SiteThemeService : ISiteThemeService { + public const string CurrentThemeSignal = "SiteCurrentTheme"; + private readonly IExtensionManager _extensionManager; private readonly IWorkContextAccessor _workContextAccessor; + private readonly ICacheManager _cacheManager; + private readonly ISignals _signals; + private readonly IOrchardServices _orchardServices; - public SiteThemeService(IExtensionManager extensionManager, IWorkContextAccessor workContextAccessor) { + public SiteThemeService( + IOrchardServices orchardServices, + IExtensionManager extensionManager, + IWorkContextAccessor workContextAccessor, + ICacheManager cacheManager, + ISignals signals) { + + _orchardServices = orchardServices; _extensionManager = extensionManager; _workContextAccessor = workContextAccessor; + _cacheManager = cacheManager; + _signals = signals; + Logger = NullLogger.Instance; + T = NullLocalizer.Instance; } public Localizer T { get; set; } public ILogger Logger { get; set; } public ExtensionDescriptor GetSiteTheme() { - var site = _workContextAccessor.GetContext().CurrentSite; - string currentThemeName = site.As().CurrentThemeName; - - return string.IsNullOrEmpty(currentThemeName) ? null : _extensionManager.GetExtension(currentThemeName); + string currentThemeName = GetCurrentThemeName(); + return string.IsNullOrEmpty(currentThemeName) ? null : _extensionManager.GetExtension(GetCurrentThemeName()); } public void SetSiteTheme(string themeName) { var site = _workContextAccessor.GetContext().CurrentSite; - site.As().Record.CurrentThemeName = themeName; + site.As().CurrentThemeName = themeName; + + _signals.Trigger(CurrentThemeSignal); + } + + public string GetCurrentThemeName() { + return _cacheManager.Get("CurrentThemeName", ctx => { + ctx.Monitor(_signals.When(CurrentThemeSignal)); + return _orchardServices.WorkContext.CurrentSite.As().CurrentThemeName; + }); } } -} \ No newline at end of file +} diff --git a/src/Orchard/Caching/Cache.cs b/src/Orchard/Caching/Cache.cs index 267bc48fc..ac8c449e2 100644 --- a/src/Orchard/Caching/Cache.cs +++ b/src/Orchard/Caching/Cache.cs @@ -16,11 +16,11 @@ namespace Orchard.Caching { // "Add" lambda k => CreateEntry(k, acquire), // "Update" lamdba - (k, currentEntry) => (currentEntry.Tokens.All(t => t.IsCurrent) ? currentEntry : CreateEntry(k, acquire))); + (k, currentEntry) => (currentEntry.GetTokens() != null && currentEntry.GetTokens().Any(t => !t.IsCurrent) ? CreateEntry(k, acquire) : currentEntry)); // Bubble up volatile tokens to parent context - if (CacheAquireContext.ThreadInstance != null) { - foreach (var token in entry.Tokens) + if (CacheAquireContext.ThreadInstance != null && entry.GetTokens() != null) { + foreach (var token in entry.GetTokens()) CacheAquireContext.ThreadInstance.Monitor(token); } @@ -29,8 +29,8 @@ namespace Orchard.Caching { private static CacheEntry CreateEntry(TKey k, Func, TResult> acquire) { - var entry = new CacheEntry { Tokens = new List() }; - var context = new AcquireContext(k, volatileItem => entry.Tokens.Add(volatileItem)); + var entry = new CacheEntry(); + var context = new AcquireContext(k, entry.AddToken); IAcquireContext parentContext = null; try { @@ -49,7 +49,19 @@ namespace Orchard.Caching { private class CacheEntry { public TResult Result { get; set; } - public IList Tokens { get; set; } + private IList Tokens { get; set; } + + public void AddToken(IVolatileToken volatileToken) { + if (Tokens == null) { + Tokens = new List(); + } + + Tokens.Add(volatileToken); + } + + public IEnumerable GetTokens() { + return Tokens; + } } }