using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; 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 static readonly ICacheProvider NullRequestCache = new NullCacheProvider(); private static readonly ICacheProvider NullStaticCache = new NullCacheProvider(); private static readonly IRuntimeCacheProvider NullRuntimeCache = new NullCacheProvider(); /// /// Creates a cache helper with disabled caches /// /// /// /// Good for unit testing /// public static CacheHelper CreateDisabledCacheHelper() { return new CacheHelper(NullRuntimeCache, NullStaticCache, NullRequestCache, new IsolatedRuntimeCache(t => NullRuntimeCache)); } /// /// Initializes a new instance for use in the web /// public CacheHelper() : this( new HttpRuntimeCacheProvider(HttpRuntime.Cache), new StaticCacheProvider(), new HttpRequestCacheProvider(), new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider())) { } /// /// Initializes a new instance for use in the web /// /// public CacheHelper(System.Web.Caching.Cache cache) : this( new HttpRuntimeCacheProvider(cache), new StaticCacheProvider(), new HttpRequestCacheProvider(), new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider())) { } [Obsolete("Use the constructor the specifies all dependencies")] [EditorBrowsable(EditorBrowsableState.Never)] public CacheHelper( IRuntimeCacheProvider httpCacheProvider, ICacheProvider staticCacheProvider, ICacheProvider requestCacheProvider) : this(httpCacheProvider, staticCacheProvider, requestCacheProvider, new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider())) { } /// /// Initializes a new instance based on the provided providers /// /// /// /// /// public CacheHelper( IRuntimeCacheProvider httpCacheProvider, ICacheProvider staticCacheProvider, ICacheProvider requestCacheProvider, IsolatedRuntimeCache isolatedCacheManager) { if (httpCacheProvider == null) throw new ArgumentNullException("httpCacheProvider"); if (staticCacheProvider == null) throw new ArgumentNullException("staticCacheProvider"); if (requestCacheProvider == null) throw new ArgumentNullException("requestCacheProvider"); if (isolatedCacheManager == null) throw new ArgumentNullException("isolatedCacheManager"); RuntimeCache = httpCacheProvider; StaticCache = staticCacheProvider; RequestCache = requestCacheProvider; IsolatedRuntimeCache = isolatedCacheManager; } /// /// Returns the current Request cache /// public ICacheProvider RequestCache { get; internal set; } /// /// Returns the current Runtime cache /// public ICacheProvider StaticCache { get; internal set; } /// /// Returns the current Runtime cache /// public IRuntimeCacheProvider RuntimeCache { get; internal set; } /// /// Returns the current Isolated Runtime cache manager /// public IsolatedRuntimeCache IsolatedRuntimeCache { get; internal set; } #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")] [EditorBrowsable(EditorBrowsableState.Never)] public void ClearAllCache() { RuntimeCache.ClearAllCache(); IsolatedRuntimeCache.ClearAllCaches(); } /// /// 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")] [EditorBrowsable(EditorBrowsableState.Never)] public void ClearCacheItem(string key) { RuntimeCache.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) { RuntimeCache.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")] [EditorBrowsable(EditorBrowsableState.Never)] public void ClearCacheObjectTypes() { RuntimeCache.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")] [EditorBrowsable(EditorBrowsableState.Never)] public void ClearCacheByKeySearch(string keyStartsWith) { RuntimeCache.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")] [EditorBrowsable(EditorBrowsableState.Never)] public void ClearCacheByKeyExpression(string regexString) { RuntimeCache.ClearCacheByKeyExpression(regexString); } [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] [EditorBrowsable(EditorBrowsableState.Never)] public IEnumerable GetCacheItemsByKeySearch(string keyStartsWith) { return RuntimeCache.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")] [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey) { return RuntimeCache.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")] [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey, Func getCacheItem) { return RuntimeCache.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")] [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey, TimeSpan timeout, Func getCacheItem) { return RuntimeCache.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")] [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) { return RuntimeCache.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")] [EditorBrowsable(EditorBrowsableState.Never)] public TT GetCacheItem(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout, Func getCacheItem) { return RuntimeCache.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) { var cache = GetHttpRuntimeCacheProvider(RuntimeCache); 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) { var cache = GetHttpRuntimeCacheProvider(RuntimeCache); 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 /// /// /// /// /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] [EditorBrowsable(EditorBrowsableState.Never)] public void InsertCacheItem(string cacheKey, CacheItemPriority priority, Func getCacheItem) { RuntimeCache.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 /// [Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")] [EditorBrowsable(EditorBrowsableState.Never)] public void InsertCacheItem(string cacheKey, CacheItemPriority priority, TimeSpan timeout, Func getCacheItem) { RuntimeCache.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) { var cache = GetHttpRuntimeCacheProvider(RuntimeCache); 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) { var cache = GetHttpRuntimeCacheProvider(RuntimeCache); 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 private HttpRuntimeCacheProvider GetHttpRuntimeCacheProvider(IRuntimeCacheProvider runtimeCache) { HttpRuntimeCacheProvider cache; var wrapper = RuntimeCache as IRuntimeCacheProviderWrapper; if (wrapper != null) { cache = wrapper.InnerProvider as HttpRuntimeCacheProvider; } else { cache = RuntimeCache as HttpRuntimeCacheProvider; } return cache; } } }