diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs index 36deb96dd1..27ade0f7b5 100644 --- a/src/Umbraco.Core/ApplicationContext.cs +++ b/src/Umbraco.Core/ApplicationContext.cs @@ -3,6 +3,7 @@ using System.Configuration; using System.Threading; using System.Web; using System.Web.Caching; +using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; @@ -23,27 +24,47 @@ namespace Umbraco.Core /// Constructor /// internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext) - :this() + : this(dbContext, serviceContext, true) { - if (dbContext == null) throw new ArgumentNullException("dbContext"); - if (serviceContext == null) throw new ArgumentNullException("serviceContext"); - - _databaseContext = dbContext; - _services = serviceContext; + } + /// + /// Constructor + /// + /// + /// + /// + internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, bool enableCache) + : this(enableCache) + { + if (dbContext == null) throw new ArgumentNullException("dbContext"); + if (serviceContext == null) throw new ArgumentNullException("serviceContext"); + + _databaseContext = dbContext; + _services = serviceContext; + } + /// /// Empty constructor normally reserved for unit tests when a DatabaseContext or a ServiceContext is not /// necessarily required or needs to be set after construction. /// - internal ApplicationContext() - { - //create a new application cache from the HttpRuntime.Cache - ApplicationCache = HttpRuntime.Cache == null - ? new CacheHelper(new System.Web.Caching.Cache()) - : new CacheHelper(HttpRuntime.Cache); + internal ApplicationContext() : this(true) + { } + /// + /// Constructor used to specify if we will enable application cache or not + /// + /// + internal ApplicationContext(bool enableCache) + { + //create a new application cache from the HttpRuntime.Cache + ApplicationCache = HttpRuntime.Cache == null + ? new CacheHelper(new System.Web.Caching.Cache(), enableCache) + : new CacheHelper(HttpRuntime.Cache, enableCache); + } + /// /// Singleton accessor /// diff --git a/src/Umbraco.Core/Cache/CacheProviderBase.cs b/src/Umbraco.Core/Cache/CacheProviderBase.cs new file mode 100644 index 0000000000..3bcb7373c1 --- /dev/null +++ b/src/Umbraco.Core/Cache/CacheProviderBase.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Web.Caching; + +namespace Umbraco.Core.Cache +{ + /// + /// An abstract class for implementing a cache helper + /// + /// + /// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, ETC... + /// + internal abstract class CacheProviderBase + { + public abstract void ClearAllCache(); + public abstract void ClearCacheItem(string key); + public abstract void ClearCacheObjectTypes(string typeName); + public abstract void ClearCacheObjectTypes(); + public abstract void ClearCacheByKeySearch(string keyStartsWith); + public abstract void ClearCacheByKeyExpression(string regexString); + public abstract IEnumerable GetCacheItemsByKeySearch(string keyStartsWith); + public abstract T GetCacheItem(string cacheKey); + public abstract T GetCacheItem(string cacheKey, Func getCacheItem); + public abstract T GetCacheItem(string cacheKey, TimeSpan timeout, Func getCacheItem); + public abstract T GetCacheItem(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem); + public abstract T GetCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem); + public abstract T GetCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan timeout, Func getCacheItem); + public abstract void InsertCacheItem(string cacheKey, CacheItemPriority priority, TimeSpan timeout, Func getCacheItem); + public abstract void InsertCacheItem(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan timeout, Func getCacheItem); + public abstract void InsertCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func getCacheItem); + } +} diff --git a/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs b/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs new file mode 100644 index 0000000000..af67d2959c --- /dev/null +++ b/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs @@ -0,0 +1,342 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using System.Web.Caching; +using Umbraco.Core.Logging; + +namespace Umbraco.Core.Cache +{ + /// + /// A CacheProvider that wraps the logic of the HttpRuntime.Cache + /// + internal class HttpRuntimeCacheProvider : CacheProviderBase + { + private readonly System.Web.Caching.Cache _cache; + private static readonly object Locker = new object(); + + public HttpRuntimeCacheProvider(System.Web.Caching.Cache cache) + { + _cache = cache; + } + + /// + /// Clears everything in umbraco's runtime cache, which means that not only + /// umbraco content is removed, but also other cache items from pages running in + /// the same application / website. Use with care :-) + /// + public override void ClearAllCache() + { + var cacheEnumerator = _cache.GetEnumerator(); + while (cacheEnumerator.MoveNext()) + { + _cache.Remove(cacheEnumerator.Key.ToString()); + } + } + + /// + /// Clears the item in umbraco's runtime cache with the given key + /// + /// Key + public override void ClearCacheItem(string key) + { + // NH 10 jan 2012 + // Patch by the always wonderful Stéphane Gay to avoid cache null refs + lock (Locker) + { + if (_cache[key] == null) return; + _cache.Remove(key); ; + } + } + + + /// + /// Clears all objects in the System.Web.Cache with the System.Type name as the + /// input parameter. (using [object].GetType()) + /// + /// The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument" + public override void ClearCacheObjectTypes(string typeName) + { + try + { + lock (Locker) + { + foreach (DictionaryEntry c in _cache) + { + if (_cache[c.Key.ToString()] != null + && _cache[c.Key.ToString()].GetType().ToString().InvariantEquals(typeName)) + { + _cache.Remove(c.Key.ToString()); + } + } + } + } + catch (Exception e) + { + LogHelper.Error("Cache clearing error", e); + } + } + + /// + /// Clears all objects in the System.Web.Cache with the System.Type specified + /// + public override void ClearCacheObjectTypes() + { + try + { + lock (Locker) + { + foreach (DictionaryEntry c in _cache) + { + if (_cache[c.Key.ToString()] != null + && _cache[c.Key.ToString()].GetType() == typeof(T)) + { + _cache.Remove(c.Key.ToString()); + } + } + } + } + catch (Exception e) + { + LogHelper.Error("Cache clearing error", e); + } + } + + /// + /// Clears all cache items that starts with the key passed. + /// + /// The start of the key + public override void ClearCacheByKeySearch(string keyStartsWith) + { + foreach (DictionaryEntry c in _cache) + { + if (c.Key is string && ((string)c.Key).InvariantStartsWith(keyStartsWith)) + { + ClearCacheItem((string)c.Key); + } + } + } + + /// + /// Clears all cache items that have a key that matches the regular expression + /// + /// + public override void ClearCacheByKeyExpression(string regexString) + { + foreach (DictionaryEntry c in _cache) + { + if (c.Key is string && Regex.IsMatch(((string)c.Key), regexString)) + { + ClearCacheItem((string)c.Key); + } + } + } + + public override IEnumerable GetCacheItemsByKeySearch(string keyStartsWith) + { + return (from DictionaryEntry c in _cache + where c.Key is string && ((string)c.Key).InvariantStartsWith(keyStartsWith) + select c.Value.TryConvertTo() + into attempt + where attempt.Success + select attempt.Result).ToList(); + } + + /// + /// Returns a cache item by key, does not update the cache if it isn't there. + /// + /// + /// + /// + public override TT GetCacheItem(string cacheKey) + { + var result = _cache.Get(cacheKey); + if (result == null) + { + return default(TT); + } + return result.TryConvertTo().Result; + } + + /// + /// Gets (and adds if necessary) an item from the cache with all of the default parameters + /// + /// + /// + /// + /// + public override TT GetCacheItem(string cacheKey, Func getCacheItem) + { + return GetCacheItem(cacheKey, CacheItemPriority.Normal, null, null, null, getCacheItem, Locker); + } + + /// + /// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW) + /// + /// + /// + /// This will set an absolute expiration from now until the timeout + /// + /// + public override TT GetCacheItem(string cacheKey, + TimeSpan timeout, Func getCacheItem) + { + return GetCacheItem(cacheKey, null, timeout, getCacheItem); + } + + /// + /// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW) + /// + /// + /// + /// + /// This will set an absolute expiration from now until the timeout + /// + /// + public override TT GetCacheItem(string cacheKey, + CacheItemRemovedCallback refreshAction, TimeSpan timeout, + Func getCacheItem) + { + return GetCacheItem(cacheKey, CacheItemPriority.Normal, refreshAction, timeout, getCacheItem); + } + + /// + /// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW) + /// + /// + /// + /// + /// + /// This will set an absolute expiration from now until the timeout + /// + /// + public override TT GetCacheItem(string cacheKey, + CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout, + Func getCacheItem) + { + return GetCacheItem(cacheKey, priority, refreshAction, null, timeout, getCacheItem); + } + + /// + /// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW) + /// + /// + /// + /// + /// + /// + /// This will set an absolute expiration from now until the timeout + /// + /// + public override TT GetCacheItem(string cacheKey, + CacheItemPriority priority, + CacheItemRemovedCallback refreshAction, + CacheDependency cacheDependency, + TimeSpan timeout, + Func getCacheItem) + { + return GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem, Locker); + } + + /// + /// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW) + /// + /// + /// + /// + /// + /// + /// This will set an absolute expiration from now until the timeout + /// + /// + /// + private TT GetCacheItem(string cacheKey, + CacheItemPriority priority, CacheItemRemovedCallback refreshAction, + CacheDependency cacheDependency, TimeSpan? timeout, Func getCacheItem, object syncLock) + { + var result = _cache.Get(cacheKey); + if (result == null) + { + lock (syncLock) + { + result = _cache.Get(cacheKey); + if (result == null) + { + result = getCacheItem(); + if (result != null) + { + //we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it. + _cache.Insert(cacheKey, result, cacheDependency, + timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value), + TimeSpan.Zero, priority, refreshAction); + } + } + } + } + return result.TryConvertTo().Result; + } + + /// + /// Inserts an item into the cache, if it already exists in the cache it will be replaced + /// + /// + /// + /// + /// This will set an absolute expiration from now until the timeout + /// + public override void InsertCacheItem(string cacheKey, + CacheItemPriority priority, + TimeSpan timeout, + Func getCacheItem) + { + InsertCacheItem(cacheKey, priority, null, null, timeout, getCacheItem); + } + + /// + /// Inserts an item into the cache, if it already exists in the cache it will be replaced + /// + /// + /// + /// + /// + /// This will set an absolute expiration from now until the timeout + /// + public override void InsertCacheItem(string cacheKey, + CacheItemPriority priority, + CacheDependency cacheDependency, + TimeSpan timeout, + Func getCacheItem) + { + InsertCacheItem(cacheKey, priority, null, cacheDependency, timeout, getCacheItem); + } + + /// + /// Inserts an item into the cache, if it already exists in the cache it will be replaced + /// + /// + /// + /// + /// + /// + /// This will set an absolute expiration from now until the timeout + /// + public override void InsertCacheItem(string cacheKey, + CacheItemPriority priority, + CacheItemRemovedCallback refreshAction, + CacheDependency cacheDependency, + TimeSpan? timeout, + Func getCacheItem) + { + object result = getCacheItem(); + if (result != null) + { + //we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it. + _cache.Insert(cacheKey, result, cacheDependency, + timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value), + TimeSpan.Zero, priority, refreshAction); + } + } + + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Cache/NullCacheProvider.cs b/src/Umbraco.Core/Cache/NullCacheProvider.cs new file mode 100644 index 0000000000..8178b95278 --- /dev/null +++ b/src/Umbraco.Core/Cache/NullCacheProvider.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Caching; + +namespace Umbraco.Core.Cache +{ + internal class NullCacheProvider : CacheProviderBase + { + public override void ClearAllCache() + { + } + + public override void ClearCacheItem(string key) + { + } + + public override void ClearCacheObjectTypes(string typeName) + { + } + + public override void ClearCacheObjectTypes() + { + } + + public override void ClearCacheByKeySearch(string keyStartsWith) + { + } + + public override void ClearCacheByKeyExpression(string regexString) + { + } + + public override IEnumerable GetCacheItemsByKeySearch(string keyStartsWith) + { + return Enumerable.Empty(); + } + + public override T GetCacheItem(string cacheKey) + { + return default(T); + } + + public override T GetCacheItem(string cacheKey, Func getCacheItem) + { + return getCacheItem(); + } + + public override T GetCacheItem(string cacheKey, TimeSpan timeout, Func getCacheItem) + { + return getCacheItem(); + } + + public override T GetCacheItem(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) + { + return getCacheItem(); + } + + public override T GetCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) + { + return getCacheItem(); + } + + public override T GetCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan timeout, Func getCacheItem) + { + return getCacheItem(); + } + + public override void InsertCacheItem(string cacheKey, CacheItemPriority priority, TimeSpan timeout, Func getCacheItem) + { + } + + public override void InsertCacheItem(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan timeout, Func getCacheItem) + { + } + + public override void InsertCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func getCacheItem) + { + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/CacheHelper.cs b/src/Umbraco.Core/CacheHelper.cs index 4f032a278a..bcde711df3 100644 --- a/src/Umbraco.Core/CacheHelper.cs +++ b/src/Umbraco.Core/CacheHelper.cs @@ -6,6 +6,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Web; using System.Web.Caching; +using Umbraco.Core.Cache; using Umbraco.Core.Logging; namespace Umbraco.Core @@ -17,29 +18,33 @@ namespace Umbraco.Core /// /// This class may be opened publicly at some point but needs a review of what is absoletely necessary. /// - public class CacheHelper + public class CacheHelper //: CacheProviderBase { - private readonly System.Web.Caching.Cache _cache; + private readonly bool _enableCache; + private readonly HttpRuntimeCacheProvider _httpCache; + private readonly NullCacheProvider _nullCache = new NullCacheProvider(); public CacheHelper(System.Web.Caching.Cache cache) + : this(cache, true) { - _cache = cache; } - private static readonly object Locker = new object(); - - /// - /// Clears everything in umbraco's runtime cache, which means that not only - /// umbraco content is removed, but also other cache items from pages running in - /// the same application / website. Use with care :-) - /// + internal CacheHelper(System.Web.Caching.Cache cache, bool enableCache) + { + _httpCache = new HttpRuntimeCacheProvider(cache); + _enableCache = enableCache; + } + public void ClearAllCache() { - var cacheEnumerator = _cache.GetEnumerator(); - while (cacheEnumerator.MoveNext()) - { - _cache.Remove(cacheEnumerator.Key.ToString()); - } + if (!_enableCache) + { + _nullCache.ClearAllCache(); + } + else + { + _httpCache.ClearAllCache(); + } } /// @@ -48,12 +53,13 @@ namespace Umbraco.Core /// Key public void ClearCacheItem(string key) { - // NH 10 jan 2012 - // Patch by the always wonderful Stéphane Gay to avoid cache null refs - lock (Locker) + if (!_enableCache) { - if (_cache[key] == null) return; - _cache.Remove(key);; + _nullCache.ClearCacheItem(key); + } + else + { + _httpCache.ClearCacheItem(key); } } @@ -65,23 +71,13 @@ namespace Umbraco.Core /// The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument" public void ClearCacheObjectTypes(string typeName) { - try + if (!_enableCache) { - lock (Locker) - { - foreach (DictionaryEntry c in _cache) - { - if (_cache[c.Key.ToString()] != null - && _cache[c.Key.ToString()].GetType().ToString().InvariantEquals(typeName)) - { - _cache.Remove(c.Key.ToString()); - } - } - } + _nullCache.ClearCacheObjectTypes(typeName); } - catch (Exception e) + else { - LogHelper.Error("Cache clearing error", e); + _httpCache.ClearCacheObjectTypes(typeName); } } @@ -90,23 +86,13 @@ namespace Umbraco.Core /// public void ClearCacheObjectTypes() { - try + if (!_enableCache) { - lock (Locker) - { - foreach (DictionaryEntry c in _cache) - { - if (_cache[c.Key.ToString()] != null - && _cache[c.Key.ToString()].GetType() == typeof(T)) - { - _cache.Remove(c.Key.ToString()); - } - } - } + _nullCache.ClearCacheObjectTypes(); } - catch (Exception e) + else { - LogHelper.Error("Cache clearing error", e); + _httpCache.ClearCacheObjectTypes(); } } @@ -116,13 +102,14 @@ namespace Umbraco.Core /// The start of the key public void ClearCacheByKeySearch(string keyStartsWith) { - foreach (DictionaryEntry c in _cache) - { - if (c.Key is string && ((string) c.Key).InvariantStartsWith(keyStartsWith)) - { - ClearCacheItem((string) c.Key); - } - } + if (!_enableCache) + { + _nullCache.ClearCacheByKeySearch(keyStartsWith); + } + else + { + _httpCache.ClearCacheByKeySearch(keyStartsWith); + } } /// @@ -131,23 +118,26 @@ namespace Umbraco.Core /// public void ClearCacheByKeyExpression(string regexString) { - foreach (DictionaryEntry c in _cache) + if (!_enableCache) { - if (c.Key is string && Regex.IsMatch(((string)c.Key), regexString)) - { - ClearCacheItem((string)c.Key); - } + _nullCache.ClearCacheByKeyExpression(regexString); + } + else + { + _httpCache.ClearCacheByKeyExpression(regexString); } } public IEnumerable GetCacheItemsByKeySearch(string keyStartsWith) { - return (from DictionaryEntry c in _cache - where c.Key is string && ((string) c.Key).InvariantStartsWith(keyStartsWith) - select c.Value.TryConvertTo() - into attempt - where attempt.Success - select attempt.Result).ToList(); + if (!_enableCache) + { + return _nullCache.GetCacheItemsByKeySearch(keyStartsWith); + } + else + { + return _httpCache.GetCacheItemsByKeySearch(keyStartsWith); + } } /// @@ -158,12 +148,14 @@ namespace Umbraco.Core /// public TT GetCacheItem(string cacheKey) { - var result = _cache.Get(cacheKey); - if (result == null) + if (!_enableCache) { - return default(TT); + return _nullCache.GetCacheItem(cacheKey); + } + else + { + return _httpCache.GetCacheItem(cacheKey); } - return result.TryConvertTo().Result; } /// @@ -175,7 +167,14 @@ namespace Umbraco.Core /// public TT GetCacheItem(string cacheKey, Func getCacheItem) { - return GetCacheItem(cacheKey, CacheItemPriority.Normal, null, null, null, getCacheItem, Locker); + if (!_enableCache) + { + return _nullCache.GetCacheItem(cacheKey, getCacheItem); + } + else + { + return _httpCache.GetCacheItem(cacheKey, getCacheItem); + } } /// @@ -189,7 +188,14 @@ namespace Umbraco.Core public TT GetCacheItem(string cacheKey, TimeSpan timeout, Func getCacheItem) { - return GetCacheItem(cacheKey, null, timeout, getCacheItem); + if (!_enableCache) + { + return _nullCache.GetCacheItem(cacheKey, timeout, getCacheItem); + } + else + { + return _httpCache.GetCacheItem(cacheKey, timeout, getCacheItem); + } } /// @@ -205,7 +211,14 @@ namespace Umbraco.Core CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) { - return GetCacheItem(cacheKey, CacheItemPriority.Normal, refreshAction, timeout, getCacheItem); + if (!_enableCache) + { + return _nullCache.GetCacheItem(cacheKey, refreshAction, timeout, getCacheItem); + } + else + { + return _httpCache.GetCacheItem(cacheKey, refreshAction, timeout, getCacheItem); + } } /// @@ -222,7 +235,14 @@ namespace Umbraco.Core CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) { - return GetCacheItem(cacheKey, priority, refreshAction, null, timeout, getCacheItem); + if (!_enableCache) + { + return _nullCache.GetCacheItem(cacheKey, priority, refreshAction, timeout, getCacheItem); + } + else + { + return _httpCache.GetCacheItem(cacheKey, priority, refreshAction, timeout, getCacheItem); + } } /// @@ -243,49 +263,16 @@ namespace Umbraco.Core TimeSpan timeout, Func getCacheItem) { - return GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem, Locker); + if (!_enableCache) + { + return _nullCache.GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem); + } + else + { + return _httpCache.GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem); + } } - - /// - /// This is used only for legacy purposes as I did not want to change all of the locking to one lock found on this object, - /// however, the reason this is used for legacy purposes is because I see zero reason to use different sync locks, just the one - /// lock (Locker) on this class should be sufficient. - /// - /// - /// - /// - /// - /// - /// This will set an absolute expiration from now until the timeout - /// - /// - /// - internal TT GetCacheItem(string cacheKey, - CacheItemPriority priority, CacheItemRemovedCallback refreshAction, - CacheDependency cacheDependency, TimeSpan? timeout, Func getCacheItem, object syncLock) - { - var result = _cache.Get(cacheKey); - if (result == null) - { - lock (syncLock) - { - result = _cache.Get(cacheKey); - if (result == null) - { - result = getCacheItem(); - if (result != null) - { - //we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it. - _cache.Insert(cacheKey, result, cacheDependency, - timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value), - TimeSpan.Zero, priority, refreshAction); - } - } - } - } - return result.TryConvertTo().Result; - } - + /// /// Inserts an item into the cache, if it already exists in the cache it will be replaced /// @@ -299,7 +286,14 @@ namespace Umbraco.Core TimeSpan timeout, Func getCacheItem) { - InsertCacheItem(cacheKey, priority, null, null, timeout, getCacheItem); + if (!_enableCache) + { + _nullCache.InsertCacheItem(cacheKey, priority, timeout, getCacheItem); + } + else + { + _httpCache.InsertCacheItem(cacheKey, priority, timeout, getCacheItem); + } } /// @@ -317,7 +311,14 @@ namespace Umbraco.Core TimeSpan timeout, Func getCacheItem) { - InsertCacheItem(cacheKey, priority, null, cacheDependency, timeout, getCacheItem); + if (!_enableCache) + { + _nullCache.InsertCacheItem(cacheKey, priority, cacheDependency, timeout, getCacheItem); + } + else + { + _httpCache.InsertCacheItem(cacheKey, priority, cacheDependency, timeout, getCacheItem); + } } /// @@ -337,14 +338,14 @@ namespace Umbraco.Core TimeSpan? timeout, Func getCacheItem) { - object result = getCacheItem(); - if (result != null) - { - //we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it. - _cache.Insert(cacheKey, result, cacheDependency, - timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value), - TimeSpan.Zero, priority, refreshAction); - } + if (!_enableCache) + { + _nullCache.InsertCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem); + } + else + { + _httpCache.InsertCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem); + } } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index edc730c879..477e3696e8 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -111,8 +111,11 @@ + + + diff --git a/src/Umbraco.Tests/BusinessLogic/BaseTest.cs b/src/Umbraco.Tests/BusinessLogic/BaseTest.cs index 1ea9110f5d..90944c4e32 100644 --- a/src/Umbraco.Tests/BusinessLogic/BaseTest.cs +++ b/src/Umbraco.Tests/BusinessLogic/BaseTest.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.BusinessLogic [SetUp] public void Initialize() { - ApplicationContext.Current = new ApplicationContext(){IsReady = true}; + ApplicationContext.Current = new ApplicationContext(false){IsReady = true}; InitializeDatabase(); InitializeApps(); InitializeAppConfigFile(); diff --git a/src/Umbraco.Tests/Macros/MacroTests.cs b/src/Umbraco.Tests/Macros/MacroTests.cs index ba6bfffc8c..19a0a4c14f 100644 --- a/src/Umbraco.Tests/Macros/MacroTests.cs +++ b/src/Umbraco.Tests/Macros/MacroTests.cs @@ -18,7 +18,8 @@ namespace Umbraco.Tests.Macros [SetUp] public void Setup() { - ApplicationContext.Current = new ApplicationContext(); + //we DO want cache enabled for these tests + ApplicationContext.Current = new ApplicationContext(true); } [TearDown] diff --git a/src/Umbraco.Tests/Persistence/BaseTableByTableTest.cs b/src/Umbraco.Tests/Persistence/BaseTableByTableTest.cs index 37659fd5d0..f8f56d6dcb 100644 --- a/src/Umbraco.Tests/Persistence/BaseTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/BaseTableByTableTest.cs @@ -32,7 +32,12 @@ namespace Umbraco.Tests.Persistence //assign the db context new DatabaseContext(new DefaultDatabaseFactory()), //assign the service context - new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy())) { IsReady = true }; + new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()), + //disable cache + false) + { + IsReady = true + }; Resolution.Freeze(); } diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index 099ddfa4c2..420905536d 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -21,7 +21,7 @@ namespace Umbraco.Tests.Persistence _dbContext = new DatabaseContext(new DefaultDatabaseFactory()); //unfortunately we have to set this up because the PetaPocoExtensions require singleton access - ApplicationContext.Current = new ApplicationContext + ApplicationContext.Current = new ApplicationContext(false) { DatabaseContext = _dbContext, IsReady = true diff --git a/src/Umbraco.Tests/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/PublishedCache/PublishedContentCacheTests.cs index f25cb9b315..f1c5db3d24 100644 --- a/src/Umbraco.Tests/PublishedCache/PublishedContentCacheTests.cs +++ b/src/Umbraco.Tests/PublishedCache/PublishedContentCacheTests.cs @@ -70,6 +70,9 @@ namespace Umbraco.Tests.PublishedCache { TestHelper.SetupLog4NetForTests(); + //create the app context + ApplicationContext.Current = new ApplicationContext(false); + _httpContextFactory = new FakeHttpContextFactory("~/Home"); //ensure the StateHelper is using our custom context StateHelper.HttpContext = _httpContextFactory.HttpContext; @@ -85,8 +88,8 @@ namespace Umbraco.Tests.PublishedCache }; _umbracoContext = new UmbracoContext( - _httpContextFactory.HttpContext, - new ApplicationContext(), + _httpContextFactory.HttpContext, + ApplicationContext.Current, cache, new PublishedMediaCache()); diff --git a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs index a2c09469b3..4ee5868e77 100644 --- a/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/NiceUrlsProviderWithDomainsTests.cs @@ -23,6 +23,11 @@ namespace Umbraco.Tests.Routing TestHelper.DropForeignKeys("umbracoDomains"); } + protected override DatabaseBehavior DatabaseTestBehavior + { + get { return DatabaseBehavior.NewSchemaPerFixture; } + } + protected override void FreezeResolution() { SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper()); diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index b9dd4c1a4a..a749765fa7 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -60,7 +60,12 @@ namespace Umbraco.Tests.TestHelpers //assign the db context new DatabaseContext(new DefaultDatabaseFactory()), //assign the service context - new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy())) { IsReady = true }; + new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()), + //disable cache + false) + { + IsReady = true + }; DatabaseContext.Initialize(); diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs index 0870862cc1..8b46559528 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs @@ -64,7 +64,12 @@ namespace Umbraco.Tests.TestHelpers //assign the db context new DatabaseContext(new DefaultDatabaseFactory()), //assign the service context - new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy())) { IsReady = true }; + new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()), + //disable cache + false) + { + IsReady = true + }; SqlSyntaxContext.SqlSyntaxProvider = SyntaxProvider; diff --git a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs index 354a69af50..1979df306c 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs @@ -61,7 +61,8 @@ namespace Umbraco.Tests.TestHelpers /// protected virtual void SetupApplicationContext() { - ApplicationContext.Current = new ApplicationContext {IsReady = true}; + //DO NOT ENABLE CACHE + ApplicationContext.Current = new ApplicationContext(false) {IsReady = true}; } /// diff --git a/src/umbraco.cms/businesslogic/cache/Cache.cs b/src/umbraco.cms/businesslogic/cache/Cache.cs index fb53436a40..6669d369bf 100644 --- a/src/umbraco.cms/businesslogic/cache/Cache.cs +++ b/src/umbraco.cms/businesslogic/cache/Cache.cs @@ -118,7 +118,7 @@ namespace umbraco.cms.businesslogic.cache { var helper = new CacheHelper(System.Web.HttpRuntime.Cache); Func f = () => getCacheItem(); - return helper.GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, f, syncLock); + return helper.GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, f); } } }