// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) James South. // Licensed under the Apache License, Version 2.0. // // // Encapsulates methods that allow the caching and retrieval of objects from the in memory cache. // // -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessor.Web.Caching { #region Using using System; using System.Collections.Generic; using System.Runtime.Caching; #endregion /// /// Encapsulates methods that allow the caching and retrieval of objects from the in memory cache. /// internal static class MemCache { #region Fields /// /// The cache /// private static readonly ObjectCache Cache = MemoryCache.Default; /// /// An internal list of cache keys to allow bulk removal. /// private static readonly Dictionary CacheItems = new Dictionary(); #endregion #region Methods /// /// Adds an item to the cache. /// /// /// A unique identifier for the cache entry. /// /// /// The object to insert. /// /// /// Optional. An object that contains eviction details for the cache entry. This object /// provides more options for eviction than a simple absolute expiration. The default value for the optional parameter /// is null. /// /// /// Optional. A named region in the cache to which the cache entry can be added, /// if regions are implemented. The default value for the optional parameter /// is null. /// /// /// True if the insertion try succeeds, or false if there is an already an entry /// in the cache with the same key as key. /// public static bool AddItem(string key, object value, CacheItemPolicy policy = null, string regionName = null) { bool isAdded; lock (Cache) { if (policy == null) { // Create a new cache policy with the default values policy = new CacheItemPolicy(); } isAdded = Cache.Add(key, value, policy, regionName); if (isAdded) { CacheItems.Add(key, regionName); } } return isAdded; } /// /// Fetches an item matching the given key from the cache. /// /// /// A unique identifier for the cache entry. /// /// /// Optional. A named region in the cache to which the cache entry can be added, /// if regions are implemented. The default value for the optional parameter /// is null. /// /// /// The cache entry that is identified by key. /// public static object GetItem(string key, string regionName = null) { return Cache.Get(key, regionName); } /// /// Updates an item to the cache. /// /// /// A unique identifier for the cache entry. /// /// /// The object to insert. /// /// /// Optional. An object that contains eviction details for the cache entry. This object /// provides more options for eviction than a simple absolute expiration. The default value for the optional parameter /// is null. /// /// /// Optional. A named region in the cache to which the cache entry can be added, /// if regions are implemented. The default value for the optional parameter /// is null. /// /// /// True if the update try succeeds, or false if there is an already an entry /// in the cache with the same key as key. /// public static bool UpdateItem(string key, object value, CacheItemPolicy policy = null, string regionName = null) { bool isUpDated = true; // Remove the item from the cache if it already exists. MemoryCache will // not add an item with an existing name. if (GetItem(key, regionName) != null) { isUpDated = RemoveItem(key, regionName); } if (policy == null) { // Create a new cache policy with the default values policy = new CacheItemPolicy(); } if (isUpDated) { isUpDated = AddItem(key, value, policy, regionName); } return isUpDated; } /// /// Removes an item matching the given key from the cache. /// /// /// A unique identifier for the cache entry. /// /// /// Optional. A named region in the cache to which the cache entry can be added, /// if regions are implemented. The default value for the optional parameter /// is null. /// /// /// True if the removal try succeeds, or false if there is an already an entry /// in the cache with the same key as key. /// public static bool RemoveItem(string key, string regionName = null) { bool isRemoved; lock (Cache) { isRemoved = Cache.Remove(key, regionName) != null; if (isRemoved) { CacheItems.Remove(key); } } return isRemoved; } /// /// Clears the cache. /// /// /// The region name. /// /// /// The . /// public static bool Clear(string regionName = null) { bool isCleared = false; lock (CacheItems) { // You can't remove items from a collection whilst you are iterating over it so you need to // create a collection to store the items to remove. Dictionary tempDictionary = new Dictionary(); foreach (KeyValuePair cacheItem in CacheItems) { // Does the cached key come with a region. if ((cacheItem.Value == null) || (cacheItem.Value != null && cacheItem.Value.Equals(regionName, StringComparison.OrdinalIgnoreCase))) { isCleared = RemoveItem(cacheItem.Key, cacheItem.Value); if (isCleared) { tempDictionary.Add(cacheItem.Key, cacheItem.Value); } } } if (isCleared) { // Loop through and clear out the dictionary of cache keys. foreach (KeyValuePair cacheItem in tempDictionary) { CacheItems.Remove(cacheItem.Key); } } } return isCleared; } #endregion } }