2016-05-18 23:34:56 +02:00
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.Web ;
using System.Web.Caching ;
namespace Umbraco.Core.Cache
{
/// <summary>
/// Class that is exposed by the ApplicationContext for application wide caching purposes
/// </summary>
public class CacheHelper
{
private static readonly ICacheProvider NullRequestCache = new NullCacheProvider ( ) ;
private static readonly ICacheProvider NullStaticCache = new NullCacheProvider ( ) ;
private static readonly IRuntimeCacheProvider NullRuntimeCache = new NullCacheProvider ( ) ;
/// <summary>
/// Creates a cache helper with disabled caches
/// </summary>
/// <returns></returns>
/// <remarks>
/// Good for unit testing
/// </remarks>
public static CacheHelper CreateDisabledCacheHelper ( )
{
return new CacheHelper ( NullRuntimeCache , NullStaticCache , NullRequestCache , new IsolatedRuntimeCache ( t = > NullRuntimeCache ) ) ;
}
/// <summary>
/// Initializes a new instance for use in the web
/// </summary>
public CacheHelper ( )
: this (
new HttpRuntimeCacheProvider ( HttpRuntime . Cache ) ,
new StaticCacheProvider ( ) ,
new HttpRequestCacheProvider ( ) ,
new IsolatedRuntimeCache ( t = > new ObjectCacheRuntimeCacheProvider ( ) ) )
{
}
/// <summary>
/// Initializes a new instance for use in the web
/// </summary>
/// <param name="cache"></param>
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 ( ) ) )
{
}
/// <summary>
/// Initializes a new instance based on the provided providers
/// </summary>
/// <param name="httpCacheProvider"></param>
/// <param name="staticCacheProvider"></param>
/// <param name="requestCacheProvider"></param>
/// <param name="isolatedCacheManager"></param>
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 ;
}
/// <summary>
/// Returns the current Request cache
/// </summary>
public ICacheProvider RequestCache { get ; internal set ; }
/// <summary>
/// Returns the current Runtime cache
/// </summary>
public ICacheProvider StaticCache { get ; internal set ; }
/// <summary>
/// Returns the current Runtime cache
/// </summary>
public IRuntimeCacheProvider RuntimeCache { get ; internal set ; }
/// <summary>
/// Returns the current Isolated Runtime cache manager
/// </summary>
public IsolatedRuntimeCache IsolatedRuntimeCache { get ; internal set ; }
#region Legacy Runtime / Http Cache accessors
/// <summary>
/// Clears the item in umbraco's runtime cache
/// </summary>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearAllCache ( )
{
RuntimeCache . ClearAllCache ( ) ;
IsolatedRuntimeCache . ClearAllCaches ( ) ;
}
/// <summary>
/// Clears the item in umbraco's runtime cache with the given key
/// </summary>
/// <param name="key">Key</param>
[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 ) ;
}
/// <summary>
/// Clears all objects in the System.Web.Cache with the System.Type name as the
/// input parameter. (using [object].GetType())
/// </summary>
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
public void ClearCacheObjectTypes ( string typeName )
{
RuntimeCache . ClearCacheObjectTypes ( typeName ) ;
}
/// <summary>
/// Clears all objects in the System.Web.Cache with the System.Type specified
/// </summary>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public void ClearCacheObjectTypes < T > ( )
{
RuntimeCache . ClearCacheObjectTypes < T > ( ) ;
}
/// <summary>
/// Clears all cache items that starts with the key passed.
/// </summary>
/// <param name="keyStartsWith">The start of the key</param>
[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 ) ;
}
/// <summary>
/// Clears all cache items that have a key that matches the regular expression
/// </summary>
/// <param name="regexString"></param>
[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 < T > GetCacheItemsByKeySearch < T > ( string keyStartsWith )
{
return RuntimeCache . GetCacheItemsByKeySearch < T > ( keyStartsWith ) ;
}
/// <summary>
/// Returns a cache item by key, does not update the cache if it isn't there.
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public TT GetCacheItem < TT > ( string cacheKey )
{
return RuntimeCache . GetCacheItem < TT > ( cacheKey ) ;
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache with all of the default parameters
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public TT GetCacheItem < TT > ( string cacheKey , Func < TT > getCacheItem )
{
return RuntimeCache . GetCacheItem < TT > ( cacheKey , getCacheItem ) ;
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public TT GetCacheItem < TT > ( string cacheKey ,
TimeSpan timeout , Func < TT > getCacheItem )
{
return RuntimeCache . GetCacheItem < TT > ( cacheKey , getCacheItem , timeout ) ;
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="refreshAction"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public TT GetCacheItem < TT > ( string cacheKey ,
CacheItemRemovedCallback refreshAction , TimeSpan timeout ,
Func < TT > getCacheItem )
{
return RuntimeCache . GetCacheItem < TT > ( cacheKey , getCacheItem , timeout , removedCallback : refreshAction ) ;
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="refreshAction"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public TT GetCacheItem < TT > ( string cacheKey ,
CacheItemPriority priority , CacheItemRemovedCallback refreshAction , TimeSpan timeout ,
Func < TT > getCacheItem )
{
return RuntimeCache . GetCacheItem < TT > ( cacheKey , getCacheItem , timeout , false , priority , refreshAction ) ;
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="refreshAction"></param>
/// <param name="cacheDependency"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[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 < TT > ( string cacheKey ,
CacheItemPriority priority ,
CacheItemRemovedCallback refreshAction ,
CacheDependency cacheDependency ,
TimeSpan timeout ,
Func < TT > 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 < TT > ( ) . Result ;
}
throw new InvalidOperationException ( "Cannot use this obsoleted overload when the current provider is not of type " + typeof ( HttpRuntimeCacheProvider ) ) ;
}
/// <summary>
/// Gets (and adds if necessary) an item from the cache
/// </summary>
/// <typeparam name="TT"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="cacheDependency"></param>
/// <param name="getCacheItem"></param>
/// <returns></returns>
[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 < TT > ( string cacheKey ,
CacheItemPriority priority ,
CacheDependency cacheDependency ,
Func < TT > 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 < TT > ( ) . Result ;
}
throw new InvalidOperationException ( "Cannot use this obsoleted overload when the current provider is not of type " + typeof ( HttpRuntimeCacheProvider ) ) ;
}
/// <summary>
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="getCacheItem"></param>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public void InsertCacheItem < T > ( string cacheKey ,
CacheItemPriority priority ,
Func < T > getCacheItem )
{
RuntimeCache . InsertCacheItem < T > ( cacheKey , getCacheItem , priority : priority ) ;
}
/// <summary>
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
[Obsolete("Do not use this method, access the runtime cache from the RuntimeCache property")]
[EditorBrowsable(EditorBrowsableState.Never)]
public void InsertCacheItem < T > ( string cacheKey ,
CacheItemPriority priority ,
TimeSpan timeout ,
Func < T > getCacheItem )
{
RuntimeCache . InsertCacheItem < T > ( cacheKey , getCacheItem , timeout , priority : priority ) ;
}
/// <summary>
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="cacheDependency"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
[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 < T > ( string cacheKey ,
CacheItemPriority priority ,
CacheDependency cacheDependency ,
TimeSpan timeout ,
Func < T > 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 ) ) ;
}
/// <summary>
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cacheKey"></param>
/// <param name="priority"></param>
/// <param name="refreshAction"></param>
/// <param name="cacheDependency"></param>
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
/// <param name="getCacheItem"></param>
[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 < T > ( string cacheKey ,
CacheItemPriority priority ,
CacheItemRemovedCallback refreshAction ,
CacheDependency cacheDependency ,
TimeSpan ? timeout ,
Func < T > 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 ;
}
}
}