本文定义 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 = ;
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 + ));
}
}
return (list as ICollection);
}
} public CacheSettings Settings
{
get
{
return this._settings;
}
}
}

CacheItemPriority.cs

using System;

public enum CacheItemPriority
{
Default = ,
High = ,
Low = ,
Normal = ,
NotRemovable =
}

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 = ;
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()
};
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(, key, value, DateTime.Now.Add(timeSpan));
} public void AddWithFileDependency(string key, object value, string fullFileNameOfFileDependency)
{
this.Add(key, value, new TimeSpan(, , , ));
} 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);
}
}

谢谢浏览!

定义 ICache 接口,以及实现默认的 ASP.NET 缓存机制的更多相关文章

  1. 概述ASP.NET缓存机制

    PetShop之ASP.NET缓存机制 如果对微型计算机硬件系统有足够的了解,那么我们对于Cache这个名词一定是耳熟能详的.在CPU以及主板的芯片中,都引入了这种名为高速缓冲存储器(Cache)的技 ...

  2. 学习ASP.NET缓存机制

    缓存是大型BS架构网站的性能优化通用手段,之前知道有这个概念,并且也知道很重要,但是一直没静下心来了解.这次借着学习PetShop源码的机会熟悉一下ASP.NET基本的缓存机制(生产环境中的真实缓存有 ...

  3. 详解ASP.NET缓存机制

    文中对ASP.NET的缓存机制进行了简述,ASP.NET中的缓存极大的简化了开发人员的使用,如果使用得当,程序性能会有客观的提升.缓存是在内存存储数据的一项技术,也是ASP.NET中提供的重要特性之一 ...

  4. java中接口的定义和接口的实现

    1.接口的定义 使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成.定义接口的基本格式如下: [修饰符] interfa ...

  5. [二] java8 函数式接口详解 函数接口详解 lambda表达式 匿名函数 方法引用使用含义 函数式接口实例 如何定义函数式接口

    函数式接口详细定义 package java.lang; import java.lang.annotation.*; /** * An informative annotation type use ...

  6. JDK8.0接口中的默认方法和静态方法

    我们在接口中通常定义的方法是抽象方法,即没有方法体,只有返回值类型和方法名:(public abstract) void Method(); 类在实现接口的时候必须重写抽象方法才可以 jdk8中新加的 ...

  7. C++:如何正确的定义一个接口类

    C++中如何定义接口类?首先给接口类下了定义:接口类应该是只提供方法声明,而自身不提供方法定义的抽象类.接口类自身不能实例化,接口类的方法定义/实现只能由接口类的子类来完成. 而对于C++,其接口类一 ...

  8. Java8新特性_接口中的默认方法

    默认方法由来猜想 1. Collection接口.Collections公共类.  同是操作集合,为啥要搞俩?没必要.在接口中搞一些默认实现,一个接口即搞定了. 2. Java8支持Lambda表达式 ...

  9. Java 8 接口中的默认方法与静态方法

    Java 8 接口中的默认方法与静态方法 1. 接口中的默认方法 允许接口中包含具有具体实现的方法,该方法称"默认方法",默认方法使用用 default 关键字修饰. public ...

随机推荐

  1. JMeter模拟多个用户进行登录

    1.将用户名密码保存在cvs或txt文件中格式为 username1,password1 username2,password2 username3,password4 一行一个,用户名和密码之间使用 ...

  2. jquery动态刷新局部表单

    想实现一个效果就是选择某个年份:然后再action中按该年份查找数据库中的数据,返回到页面表单中显示. 1.添加登记年度的changge事件,也是异步请求. $(document).ready(fun ...

  3. oracle_修改Oracle数据库字符集 AL32UTF8;

    修改数据库字符集 以支持维文等  utf8 停掉库 进入装载模式 ALTER SYSTEM ENABLE RESTRICTED SESSION; ALTER SYSTEM SET JOB_QUEUE_ ...

  4. 手工制作的年份Java老A发售量

    Java老A这本书是写了很长的时间,昨天终于开始china-pub.京东.活动当天发售的猫,现在,简称买卖,他当然还没有到. 有兴趣的人能够去看看哈(兴许其它站点地址也会在这里公开): china-p ...

  5. Linux 解决文件删除,但并没有改变磁盘可用性

    昨天收到zabbix警报邮件,有一个server的 /home 文件夹的使用达成90%以上.检查,发现MongoDB数据文件到这个文件夹.高.而这个MongoDB的数据如今又都不用了.于是就直接把它的 ...

  6. div中显示某个网页

    原文:div中显示某个网页 1.<iframe>方法 2.ajax方法 ajax+流实现无框架限制块刷新: 主框架index页面: js: $(function(){ $("#d ...

  7. Linux线程 之 线程 线程组 进程 轻量级进程(LWP)

    Thread Local Storage,线程本地存储,大神Ulrich Drepper有篇PDF文档是讲TLS的,我曾经努力过三次尝试搞清楚TLS的原理,均没有彻底搞清楚.这一次是第三次,我沉浸gl ...

  8. jquery+css3打造一款ajax分页插件

    原文:[原创]jquery+css3打造一款ajax分页插件 最近公司的项目将好多分页改成了ajax的前台分页以前写的分页插件就不好用了,遂重写一个 支持IE6+,但没有动画效果如果没有硬需求,个人认 ...

  9. exec 重定向

    文件中常用的重定向: command > filename把把标准输出重定向到一个新文件中command >> filename 把把标准输出重定向到一个文件中 (追加)comman ...

  10. Java JDK 8 安装和环境变量的配置(Linux and Windows)

    Java JDK 8 的安装以及环境变量的配置(Linux and Windows) JDK(Java Development Kit)包含了Java语言的编译器,能够在这里下载: http://ww ...