/// <summary> /// Retrieves the object by the specified key from the cache. If the object does not exist in the cache, it will be added. /// </summary> /// <typeparam name="T">Type of object to return</typeparam> /// <param name="cache">Cache to work with</param> /// <param name="key">Cache key for the object</param> /// <param name="cacheAction">Action to perform if the object does not exist in the cache.</param> /// <returns></returns> public static T GetOrCache <T>(this ICacheClient cache, string key, Func <ICacheContext, T> cacheAction) where T : class { var item = cache.Get <T>(key); var eventArgs = new CacheHitEventArgs { CacheKey = key, Type = typeof(T) }; if (item == null) { CacheStackSettings.OnCacheMiss(cache, eventArgs); var context = new CacheContext(cache); item = cacheAction(context); // No need to cache null values if (item != null) { cache.CacheAndSetTriggers(context, key, item); } } else { CacheStackSettings.OnCacheHit(cache, eventArgs); } return(item); }
/// <summary> /// Caches the specified item using the context information /// </summary> /// <typeparam name="T">Type of object to cache</typeparam> /// <param name="cache">Cache to store the object</param> /// <param name="context">Context information for how to cache the object</param> /// <param name="key">Cache key</param> /// <param name="item">Item to cache</param> public static void CacheAndSetTriggers <T>(this ICacheClient cache, CacheContext context, string key, T item) { // Don't cache if there is no context if (context == null) { return; } // Don't cache if there are no profile durations configured if (CacheStackSettings.CacheProfileDurations == null) { return; } var expiration = CacheStackSettings.CacheProfileDurations(context.CacheProfile); cache.Set(key, item, expiration); // Rip through all other keys for this object type and add the item under those cache keys too var itemType = typeof(T); if (CacheStackSettings.CacheKeysForObject != null && CacheStackSettings.CacheKeysForObject.ContainsKey(itemType)) { var keys = CacheStackSettings.CacheKeysForObject[itemType](item).ToList(); // Only setup the other cache keys if the current key exists in them. Should prevent some undesirable results if caching partial objects if (keys.Any(x => x == key)) { foreach (var k in keys) { if (k == key) { continue; } cache.Set(k, item, expiration); AddKeyToTriggers(context, k); } } } AddKeyToTriggers(context, key); }