using System; using System.Collections; using System.Collections.Generic; using System.Linq; 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 { /// /// Class that is exposed by the ApplicationContext for application wide caching purposes /// public class CacheHelper { private readonly bool _enableCache; private readonly ICacheProvider _requestCache; private readonly ICacheProvider _nullRequestCache = new NullCacheProvider(); private readonly ICacheProvider _staticCache; private readonly ICacheProvider _nullStaticCache = new NullCacheProvider(); private readonly IRuntimeCacheProvider _httpCache; private readonly IRuntimeCacheProvider _nullHttpCache = new NullCacheProvider(); /// /// Creates a cache helper with disabled caches /// /// /// /// Good for unit testing /// public static CacheHelper CreateDisabledCacheHelper() { return new CacheHelper(null, null, null, false); } /// /// Initializes a new instance for use in the web /// public CacheHelper() : this( new HttpRuntimeCacheProvider(HttpRuntime.Cache), new StaticCacheProvider(), new HttpRequestCacheProvider()) { } /// /// Initializes a new instance for use in the web /// /// public CacheHelper(System.Web.Caching.Cache cache) : this( new HttpRuntimeCacheProvider(cache), new StaticCacheProvider(), new HttpRequestCacheProvider()) { } /// /// Initializes a new instance based on the provided providers /// /// /// /// public CacheHelper( IRuntimeCacheProvider httpCacheProvider, ICacheProvider staticCacheProvider, ICacheProvider requestCacheProvider) : this(httpCacheProvider, staticCacheProvider, requestCacheProvider, true) { } /// /// Private ctor used for creating a disabled cache helper /// /// /// /// /// private CacheHelper( IRuntimeCacheProvider httpCacheProvider, ICacheProvider staticCacheProvider, ICacheProvider requestCacheProvider, bool enableCache) { if (enableCache) { _httpCache = httpCacheProvider; _staticCache = staticCacheProvider; _requestCache = requestCacheProvider; } else { _httpCache = null; _staticCache = null; _requestCache = null; } _enableCache = enableCache; } /// /// Returns the current Request cache /// public ICacheProvider RequestCache { get { return _enableCache ? _requestCache : _nullRequestCache; } } /// /// Returns the current Runtime cache /// public ICacheProvider StaticCache { get { return _enableCache ? _staticCache : _nullStaticCache; } } /// /// Returns the current Runtime cache /// public IRuntimeCacheProvider RuntimeCache { get { return _enableCache ? _httpCache : _nullHttpCache; } } #region Legacy Runtime/Http Cache accessors /// /// Clears the item in umbraco's runtime cache /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public void ClearAllCache() { if (_enableCache == false) { _nullHttpCache.ClearAllCache(); } else { _httpCache.ClearAllCache(); } } /// /// Clears the item in umbraco's runtime cache with the given key /// /// Key [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public void ClearCacheItem(string key) { if (_enableCache == false) { _nullHttpCache.ClearCacheItem(key); } else { _httpCache.ClearCacheItem(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" [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public void ClearCacheObjectTypes(string typeName) { if (_enableCache == false) { _nullHttpCache.ClearCacheObjectTypes(typeName); } else { _httpCache.ClearCacheObjectTypes(typeName); } } /// /// Clears all objects in the System.Web.Cache with the System.Type specified /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public void ClearCacheObjectTypes() { if (_enableCache == false) { _nullHttpCache.ClearCacheObjectTypes(); } else { _httpCache.ClearCacheObjectTypes(); } } /// /// Clears all cache items that starts with the key passed. /// /// The start of the key [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public void ClearCacheByKeySearch(string keyStartsWith) { if (_enableCache == false) { _nullHttpCache.ClearCacheByKeySearch(keyStartsWith); } else { _httpCache.ClearCacheByKeySearch(keyStartsWith); } } /// /// Clears all cache items that have a key that matches the regular expression /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public void ClearCacheByKeyExpression(string regexString) { if (_enableCache == false) { _nullHttpCache.ClearCacheByKeyExpression(regexString); } else { _httpCache.ClearCacheByKeyExpression(regexString); } } [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public IEnumerable GetCacheItemsByKeySearch(string keyStartsWith) { if (_enableCache == false) { return _nullHttpCache.GetCacheItemsByKeySearch(keyStartsWith); } else { return _httpCache.GetCacheItemsByKeySearch(keyStartsWith); } } /// /// Returns a cache item by key, does not update the cache if it isn't there. /// /// /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public TT GetCacheItem(string cacheKey) { if (_enableCache == false) { return _nullHttpCache.GetCacheItem(cacheKey); } else { return _httpCache.GetCacheItem(cacheKey); } } /// /// Gets (and adds if necessary) an item from the cache with all of the default parameters /// /// /// /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public TT GetCacheItem(string cacheKey, Func getCacheItem) { if (_enableCache == false) { return _nullHttpCache.GetCacheItem(cacheKey, getCacheItem); } else { return _httpCache.GetCacheItem(cacheKey, 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 /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public TT GetCacheItem(string cacheKey, TimeSpan timeout, Func getCacheItem) { if (_enableCache == false) { return _nullHttpCache.GetCacheItem(cacheKey, getCacheItem, timeout); } else { return _httpCache.GetCacheItem(cacheKey, getCacheItem, timeout); } } /// /// 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 /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public TT GetCacheItem(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) { if (!_enableCache) { return _nullHttpCache.GetCacheItem(cacheKey, getCacheItem, timeout, removedCallback: refreshAction); } else { return _httpCache.GetCacheItem(cacheKey, getCacheItem, timeout, removedCallback: refreshAction); } } /// /// 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 /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] public TT GetCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) { if (_enableCache == false) { return _nullHttpCache.GetCacheItem(cacheKey, getCacheItem, timeout, false, priority, refreshAction); } else { return _httpCache.GetCacheItem(cacheKey, getCacheItem, timeout, false, priority, refreshAction); } } /// /// 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 /// /// [Obsolete("Do not use this method, we no longer support the caching overloads with references to CacheDependency, use the overloads specifying a file collection instead")] public TT GetCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan timeout, Func getCacheItem) { if (_enableCache == false) { return _nullHttpCache.GetCacheItem(cacheKey, getCacheItem, timeout, false, priority, refreshAction, null); } else { var cache = _httpCache as HttpRuntimeCacheProvider; if (cache != null) { var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency); return result == null ? default(TT) : result.TryConvertTo().Result; } throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); } } /// /// Gets (and adds if necessary) an item from the cache /// /// /// /// /// /// /// [Obsolete("Do not use this method, we no longer support the caching overloads with references to CacheDependency, use the overloads specifying a file collection instead")] public TT GetCacheItem(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, Func getCacheItem) { if (!_enableCache) { return _nullHttpCache.GetCacheItem(cacheKey, getCacheItem, null, false, priority, null, null); } else { var cache = _httpCache as HttpRuntimeCacheProvider; if (cache != null) { var result = cache.GetCacheItem(cacheKey, () => getCacheItem(), null, false, priority, null, cacheDependency); return result == null ? default(TT) : result.TryConvertTo().Result; } throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); } } /// /// Inserts an item into the cache, if it already exists in the cache it will be replaced /// /// /// /// /// public void InsertCacheItem(string cacheKey, CacheItemPriority priority, Func getCacheItem) { if (_enableCache == false) { _nullHttpCache.InsertCacheItem(cacheKey, getCacheItem, priority: priority); } else { _httpCache.InsertCacheItem(cacheKey, getCacheItem, priority: priority); } } /// /// 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 void InsertCacheItem(string cacheKey, CacheItemPriority priority, TimeSpan timeout, Func getCacheItem) { if (_enableCache == false) { _nullHttpCache.InsertCacheItem(cacheKey, getCacheItem, timeout, priority: priority); } else { _httpCache.InsertCacheItem(cacheKey, getCacheItem, timeout, priority: priority); } } /// /// 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 /// [Obsolete("Do not use this method, we no longer support the caching overloads with references to CacheDependency, use the overloads specifying a file collection instead")] public void InsertCacheItem(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan timeout, Func getCacheItem) { if (_enableCache == false) { _nullHttpCache.InsertCacheItem(cacheKey, getCacheItem, timeout, priority: priority, dependentFiles:null); } else { var cache = _httpCache as HttpRuntimeCacheProvider; if (cache != null) { cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, null, cacheDependency); } throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); } } /// /// 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 /// [Obsolete("Do not use this method, we no longer support the caching overloads with references to CacheDependency, use the overloads specifying a file collection instead")] public void InsertCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func getCacheItem) { if (_enableCache == false) { _nullHttpCache.InsertCacheItem(cacheKey, getCacheItem, timeout, false, priority, refreshAction, null); } else { var cache = _httpCache as HttpRuntimeCacheProvider; if (cache != null) { cache.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, false, priority, refreshAction, cacheDependency); } throw new InvalidOperationException("Cannot use this obsoleted overload when the current provider is not of type " + typeof(HttpRuntimeCacheProvider)); } } #endregion } }