MemoryCache是​​否支持区域?

我需要添加缓存function,并找到一个名为MemoryCache的新shiny类。 但是,我发现MemoryCache有点瘫痪(我需要区域function)。 除了其他东西,我需要添加像ClearAll(区域)这样的东西。 作者努力保持这个类没有区域支持,代码如下:

if (regionName != null) { throw new NotSupportedException(R.RegionName_not_supported); } 

几乎每种方法都有。 我没有看到一种简单的方法来覆盖这种行为。 我能想到的添加区域支持的唯一方法是添加一个新类作为MemoryCache的包装,而不是作为一个inheritance自MemoryCache的类。 然后在这个新类中创建一个Dictionary并让每个方法“缓冲”区域调用。 听起来很讨厌和错误,但最终……

您知道向MemoryCache添加区域的更好方法吗?

我知道你问这个问题已经很久了,所以这不是你的答案,而是未来读者的补充。

我也惊讶地发现MemoryCache的标准实现不支持区域。 它很容易立即提供。 因此,我决定将MemoryCache包装在我自己的简单类中,以提供我经常需要的function。

我把我的代码放在这里,为有同样需要的人节省时间!

 ///  /// ================================================================================================================= /// This is a static encapsulation of the Framework provided MemoryCache to make it easier to use. /// - Keys can be of any type, not just strings. /// - A typed Get method is provided for the common case where type of retrieved item actually is known. /// - Exists method is provided. /// - Except for the Set method with custom policy, some specific Set methods are also provided for convenience. /// - One SetAbsolute method with remove callback is provided as an example. /// The Set method can also be used for custom remove/update monitoring. /// - Domain (or "region") functionality missing in default MemoryCache is provided. /// This is very useful when adding items with identical keys but belonging to different domains. /// Example: "Customer" with Id=1, and "Product" with Id=1 /// ================================================================================================================= ///  public static class MyCache { private const string KeySeparator = "_"; private const string DefaultDomain = "DefaultDomain"; private static MemoryCache Cache { get { return MemoryCache.Default; } } // ----------------------------------------------------------------------------------------------------------------------------- // The default instance of the MemoryCache is used. // Memory usage can be configured in standard config file. // ----------------------------------------------------------------------------------------------------------------------------- // cacheMemoryLimitMegabytes: The amount of maximum memory size to be used. Specified in megabytes. // The default is zero, which indicates that the MemoryCache instance manages its own memory // based on the amount of memory that is installed on the computer. // physicalMemoryPercentage: The percentage of physical memory that the cache can use. It is specified as an integer value from 1 to 100. // The default is zero, which indicates that the MemoryCache instance manages its own memory // based on the amount of memory that is installed on the computer. // pollingInterval: The time interval after which the cache implementation compares the current memory load with the // absolute and percentage-based memory limits that are set for the cache instance. // The default is two minutes. // ----------------------------------------------------------------------------------------------------------------------------- //  //  //  //  //  //  //  //  //  // ----------------------------------------------------------------------------------------------------------------------------- ///  /// Store an object and let it stay in cache until manually removed. ///  public static void SetPermanent(string key, object data, string domain = null) { CacheItemPolicy policy = new CacheItemPolicy { }; Set(key, data, policy, domain); } ///  /// Store an object and let it stay in cache x minutes from write. ///  public static void SetAbsolute(string key, object data, double minutes, string domain = null) { CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(minutes) }; Set(key, data, policy, domain); } ///  /// Store an object and let it stay in cache x minutes from write. /// callback is a method to be triggered when item is removed ///  public static void SetAbsolute(string key, object data, double minutes, CacheEntryRemovedCallback callback, string domain = null) { CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(minutes), RemovedCallback = callback }; Set(key, data, policy, domain); } ///  /// Store an object and let it stay in cache x minutes from last write or read. ///  public static void SetSliding(object key, object data, double minutes, string domain = null) { CacheItemPolicy policy = new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(minutes) }; Set(key, data, policy, domain); } ///  /// Store an item and let it stay in cache according to specified policy. ///  /// Key within specified domain /// Object to store /// CacheItemPolicy /// NULL will fallback to default domain public static void Set(object key, object data, CacheItemPolicy policy, string domain = null) { Cache.Add(CombinedKey(key, domain), data, policy); } ///  /// Get typed item from cache. ///  /// Key within specified domain /// NULL will fallback to default domain public static T Get(object key, string domain = null) { return (T)Get(key, domain); } ///  /// Get item from cache. ///  /// Key within specified domain /// NULL will fallback to default domain public static object Get(object key, string domain = null) { return Cache.Get(CombinedKey(key, domain)); } ///  /// Check if item exists in cache. ///  /// Key within specified domain /// NULL will fallback to default domain public static bool Exists(object key, string domain = null) { return Cache[CombinedKey(key, domain)] != null; } ///  /// Remove item from cache. ///  /// Key within specified domain /// NULL will fallback to default domain public static void Remove(object key, string domain = null) { Cache.Remove(CombinedKey(key, domain)); } #region Support Methods ///  /// Parse domain from combinedKey. /// This method is exposed publicly because it can be useful in callback methods. /// The key property of the callback argument will in our case be the combinedKey. /// To be interpreted, it needs to be split into domain and key with these parse methods. ///  public static string ParseDomain(string combinedKey) { return combinedKey.Substring(0, combinedKey.IndexOf(KeySeparator)); } ///  /// Parse key from combinedKey. /// This method is exposed publicly because it can be useful in callback methods. /// The key property of the callback argument will in our case be the combinedKey. /// To be interpreted, it needs to be split into domain and key with these parse methods. ///  public static string ParseKey(string combinedKey) { return combinedKey.Substring(combinedKey.IndexOf(KeySeparator) + KeySeparator.Length); } ///  /// Create a combined key from given values. /// The combined key is used when storing and retrieving from the inner MemoryCache instance. /// Example: Product_76 ///  /// Key within specified domain /// NULL will fallback to default domain private static string CombinedKey(object key, string domain) { return string.Format("{0}{1}{2}", string.IsNullOrEmpty(domain) ? DefaultDomain : domain, KeySeparator, key); } #endregion } 

您可以创建多个MemoryCache实例,每个实例对应一个数据分区。

http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx

您可以创建MemoryCache类的多个实例,以便在同一个应用程序和同一AppDomain实例中使用

另一种方法是在MemoryCache周围实现一个包装器,它通过组合键和区域名来实现区域,例如

 public interface ICache { ... object Get(string key, string regionName = null); ... } public class MyCache : ICache { private readonly MemoryCache cache public MyCache(MemoryCache cache) { this.cache = cache. } ... public object Get(string key, string regionName = null) { var regionKey = RegionKey(key, regionName); return cache.Get(regionKey); } private string RegionKey(string key, string regionName) { // NB Implements region as a suffix, for prefix, swap order in the format return string.IsNullOrEmpty(regionName) ? key : string.Format("{0}{1}{2}", key, "::", regionName); } ... } 

它并不完美,但它适用于大多数用例。

我实现了这个,它可以作为NuGet包使用: Meerkat.Caching