定义 ICache 接口,以及实现默认的 ASP.NET 缓存机制
2013-06-28 15:28 音乐让我说 阅读(686) 评论(0) 编辑 收藏 举报本文定义 ICache 接口,以及实现默认的 ASP.NET 缓存机制(即通过 System.Web.Caching.Cache)来缓存,将来也可以通过扩展,替换默认实现。
下面直接贴代码了:
ICache 接口
基础接口 - ICache
using System; using System.Collections; using System.Collections.Generic; public interface ICache { void Clear(); bool Contains(string key); object Get(object key); T Get<T>(object key); IList<CacheItemDescriptor> GetDescriptors(); T GetOrInsert<T>(object key, int timeToLiveInSeconds, bool slidingExpiration, Func<T> fetcher); void Insert(object key, object value); void Insert(object key, object value, int timeToLive, bool slidingExpiration); void Insert(object key, object value, int timeToLive, bool slidingExpiration, CacheItemPriority priority); void Remove(object key); void RemoveAll(ICollection keys); int Count { get; } ICollection Keys { get; } }
结束标记。
CacheAspNet
依赖 Web 运行时的缓存
using System; using System.Collections; using System.Collections.Generic; using System.Web; using System.Web.Caching; public class CacheAspNet : ICache { private Cache _cache; private CacheSettings _settings; public CacheAspNet() { this._settings = new CacheSettings(); this.Init(new CacheSettings()); } public CacheAspNet(CacheSettings settings) { this._settings = new CacheSettings(); this.Init(settings); } private string BuildKey(object key) { if (this._settings.UsePrefix) return (this._settings.PrefixForCacheKeys + "." + key.ToString()); return key.ToString(); } public void Clear() { ICollection keys = this.Keys; foreach (string str in keys) { string key = this.BuildKey(str); this._cache.Remove(key); } } public bool Contains(string key) { string str = this.BuildKey(key); if (this._cache.Get(str) == null) return false; return true; } private System.Web.Caching.CacheItemPriority ConvertToAspNetPriority(CacheItemPriority priority) { if (priority == CacheItemPriority.Normal) return System.Web.Caching.CacheItemPriority.Normal; if (priority == CacheItemPriority.High) return System.Web.Caching.CacheItemPriority.High; if (priority == CacheItemPriority.Low) return System.Web.Caching.CacheItemPriority.Low; if (priority == CacheItemPriority.Normal) return System.Web.Caching.CacheItemPriority.Normal; return System.Web.Caching.CacheItemPriority.NotRemovable; } public T Get<T>(object key) { string str = this.BuildKey(key); object obj2 = this._cache.Get(str); if (obj2 == null) return default(T); return (T) obj2; } public object Get(object key) { string str = this.BuildKey(key); return this._cache.Get(str); } public IList<CacheItemDescriptor> GetDescriptors() { IList<CacheItemDescriptor> list = new List<CacheItemDescriptor>(); IEnumerator enumerator = this.Keys.GetEnumerator(); while (enumerator.MoveNext()) { string current = enumerator.Current as string; object obj2 = this.Get(current); list.Add(new CacheItemDescriptor(current, obj2.GetType().FullName)); } ((List<CacheItemDescriptor>) list).Sort((Comparison<CacheItemDescriptor>) ((c1, c2) => c1.Key.CompareTo(c2.Key))); return list; } public T GetOrInsert<T>(object key, int timeToLiveInSeconds, bool slidingExpiration, Func<T> fetcher) { object obj2 = this.Get(key); if (obj2 == null) { T local = fetcher(); this.Insert(key, local, timeToLiveInSeconds, slidingExpiration); return local; } return (T) obj2; } private void Init(CacheSettings settings) { this._cache = HttpRuntime.Cache; this._settings = settings; } public void Insert(object key, object value) { this.Insert(key, value, this._settings.DefaultTimeToLive, this._settings.DefaultSlidingExpirationEnabled, this._settings.DefaultCachePriority); } public void Insert(object key, object value, int timeToLive, bool slidingExpiration) { this.Insert(key, value, timeToLive, slidingExpiration, this._settings.DefaultCachePriority); } public void Insert(object keyName, object value, int timeToLive, bool slidingExpiration, CacheItemPriority priority) { TimeSpan span = TimeSpan.FromSeconds((double) timeToLive); if (keyName == null) { throw new ArgumentNullException("keyName"); } if(TimeSpan.Zero > span) { throw new ArgumentException("timeToLive"); } System.Web.Caching.CacheItemPriority priority2 = this.ConvertToAspNetPriority(priority); string key = this.BuildKey(keyName); if (TimeSpan.Zero < span) { if (slidingExpiration) { this._cache.Insert(key, value, null, Cache.NoAbsoluteExpiration, span, priority2, null); } else { DateTime absoluteExpiration = DateTime.Now.AddSeconds((double)timeToLive); this._cache.Insert(key, value, null, absoluteExpiration, Cache.NoSlidingExpiration, priority2, null); } } else { this._cache.Insert(key, value, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, priority2, null); } } public void Remove(object key) { string str = this.BuildKey(key); this._cache.Remove(str); } public void RemoveAll(ICollection keys) { foreach (object obj2 in keys) { string key = this.BuildKey((string) obj2); this._cache.Remove(key); } } public int Count { get { if (!this._settings.UsePrefix) return this._cache.Count; int num = 0; foreach (DictionaryEntry entry in this._cache) { string key = (string) entry.Key; if (key.StartsWith(this._settings.PrefixForCacheKeys)) { num++; } } return num; } } public ICollection Keys { get { IList<string> list = new List<string>(); foreach (DictionaryEntry entry in this._cache) { string key = (string) entry.Key; if (!this._settings.UsePrefix) { list.Add(key); } else if (key.StartsWith(this._settings.PrefixForCacheKeys)) { list.Add(key.Substring(this._settings.PrefixForCacheKeys.Length + 1)); } } return (list as ICollection); } } public CacheSettings Settings { get { return this._settings; } } }
CacheItemPriority.cs
using System; public enum CacheItemPriority { Default = 1, High = 2, Low = 0, Normal = 1, NotRemovable = 3 }
CacheItemDescriptor.cs
using System; public class CacheItemDescriptor { private string _key; private string _serializedData; private string _type; public CacheItemDescriptor(string key, string type) : this(key, type, string.Empty) { } public CacheItemDescriptor(string key, string type, string serializedData) { this._serializedData = string.Empty; this._key = key; this._type = type; this._serializedData = serializedData; } public string Data { get { return this._serializedData; } } public string ItemType { get { return this._type; } } public string Key { get { return this._key; } } }
CacheSettings.cs
using System; public class CacheSettings { public CacheItemPriority DefaultCachePriority = CacheItemPriority.Normal; public bool DefaultSlidingExpirationEnabled = false; public int DefaultTimeToLive = 600; public string PrefixForCacheKeys = "cmnlib"; public bool UsePrefix = true; }
Cacher.cs
using System; using System.Collections; using System.Collections.Generic; public class Cacher { private static ICache _provider = new CacheAspNet(); public static void Clear() { _provider.Clear(); } public static bool Contains(string key) { return _provider.Contains(key); } public static object Get(object key) { return _provider.Get(key); } public static T Get<T>(object key) { return _provider.Get<T>(key); } public static T Get<T>(string key, int timeInSeconds, Func<T> fetcher) { return Get<T>(key, true, timeInSeconds, false, fetcher); } public static T Get<T>(string key, TimeSpan timeInSeconds, Func<T> fetcher) { return Get<T>(key, true, timeInSeconds.Seconds, false, fetcher); } public static T Get<T>(string key, bool useCache, TimeSpan timeInSeconds, Func<T> fetcher) { return Get<T>(key, useCache, timeInSeconds.Seconds, false, fetcher); } public static T Get<T>(string key, bool useCache, int timeInSeconds, bool slidingExpiration, Func<T> fetcher) { if (!useCache) return fetcher(); return _provider.GetOrInsert<T>(key, timeInSeconds, slidingExpiration, fetcher); } public static IList<CacheItemDescriptor> GetDescriptors() { return _provider.GetDescriptors(); } public static void Init(ICache cacheProvider) { _provider = cacheProvider; } public static void Insert(object key, object value) { _provider.Insert(key, value); } public static void Insert(object key, object value, int timeToLive, bool slidingExpiration) { _provider.Insert(key, value, timeToLive, slidingExpiration); } public static void Insert(object key, object value, int timeToLive, bool slidingExpiration, CacheItemPriority priority) { _provider.Insert(key, value, timeToLive, slidingExpiration, priority); } public static void Remove(object key) { _provider.Remove(key); } public static void RemoveAll(ICollection keys) { _provider.RemoveAll(keys); } public static int Count { get { return _provider.Count; } } public static ICollection Keys { get { return _provider.Keys; } } public static ICache Provider { get { return _provider; } } }
结束标记。
RuntimeMomoryCache
备注:.NET 4.0 增加了一个 System.Runtime.Caching.Momory 类,不依赖 Web。
代码如下:
public class RuntimeMemoryCache : ICache { // Fields private readonly MemoryCache _cache = MemoryCache.Default; // Methods public void Add(string key, object value, TimeSpan timeSpan) { if (!string.IsNullOrEmpty(key) && value != null) this._cache.Add(key, value, DateTimeOffset.Now.Add(timeSpan), null); } public void AddWithFileDependency(string key, object value, string fullFileNameOfFileDependency) { if (!string.IsNullOrEmpty(key) && value != null) { CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMonths(1) }; policy.ChangeMonitors.Add(new HostFileChangeMonitor(new List<string> { fullFileNameOfFileDependency })); this._cache.Add(key, value, policy, null); } } public void Clear() { foreach (string str in this._cache.AsParallel<KeyValuePair<string, object>>().ToDictionary<KeyValuePair<string, object>, string>(a => a.Key).Keys) { this._cache.Remove(str, null); } } public object Get(string cacheKey) { return this._cache[cacheKey]; } public void MarkDeletion(string key, object value, TimeSpan timeSpan) { this.Remove(key); } public void Remove(string cacheKey) { this._cache.Remove(cacheKey, null); } public void Set(string key, object value, TimeSpan timeSpan) { this._cache.Set(key, value, DateTimeOffset.Now.Add(timeSpan), null); } }
结束标记。
分布式缓存 - Memcached
利用 Memcached 实现分布式缓存。
MemcachedClient 使用的是 Enyim.Caching。开源地址:https://github.com/enyim/EnyimMemcached
public class MemcachedCache : ICache { // Fields private MemcachedClient cache = new MemcachedClient(); // Methods public void Add(string key, object value, TimeSpan timeSpan) { key = key.ToLower(); this.cache.Store(3, key, value, DateTime.Now.Add(timeSpan)); } public void AddWithFileDependency(string key, object value, string fullFileNameOfFileDependency) { this.Add(key, value, new TimeSpan(30, 0, 0, 0)); } public void Clear() { this.cache.FlushAll(); } public object Get(string cacheKey) { cacheKey = cacheKey.ToLower(); HttpContext current = HttpContext.Current; if (current != null && current.Items.Contains(cacheKey)) return current.Items[cacheKey]; object obj2 = this.cache.Get(cacheKey); if (current != null && obj2 != null) current.Items[cacheKey] = obj2; return obj2; } public Dictionary<string, Dictionary<string, string>> GetStatistics() { throw new NotImplementedException(); } public void MarkDeletion(string key, object value, TimeSpan timeSpan) { this.Set(key, value, timeSpan); } public void Remove(string cacheKey) { cacheKey = cacheKey.ToLower(); this.cache.Remove(cacheKey); } public void Set(string key, object value, TimeSpan timeSpan) { this.Add(key, value, timeSpan); } }
谢谢浏览!
作者:音乐让我说(音乐让我说 - 博客园)
出处:http://music.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。