本文定义 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. 谈论HashMap,HashSet,HashTableeasy被我们忽视

    在正常发育,HashMap,HashTable,HashSet 他们批准了经常使用的按键值地图数据结构.在这里,我主要写一些平时我们使用的这些数据结构easy忽略. HashMap HashMap的结 ...

  2. VC中MessageBox的常见用法

    一.关于MessageBox       消息框是个很常用的控件,属性比较多,本文列出了它的一些常用方法,及指出了它的一些应用场合.       1.MessageBox("这是一个最简单的 ...

  3. SQL Prompt——SQL智能提示插件

    数据库是大家在项目开发中肯定会用到的,C#项目用的最多的就是微软自家的SQL Server了.不可否认,微软的Visual Studio开发平台很好用,很直观的体现就是智能提示.敲几个字符,相关的信息 ...

  4. windows已安装solr

    下载地址:http://archive.apache.org/dist/lucene/solr/ 操作环境:  Win7,Tomcat6, Solr4.3, Jdk6 下载solr4.3的包,解压到本 ...

  5. CodeForces 14 E - Camels &amp;&amp; D - Two Paths

    D - Two paths 仅仅想到了一个o(n^2)的解法. 首先枚举删除一条边,必定得到两棵独立的树.计算两棵树的直径.保留最大乘积. 首先两条路不相交,则必定能够分到两棵子树中,由于要乘积最大, ...

  6. autorun.vbs病毒的清除办法

    症状:计算机里面出现一堆autorun为文件名称的文件,删除后出现找不到autorun.vbs的提示.我就打开当中的一个文件:Autorun.bat,内容例如以下: @echo off  //不显示系 ...

  7. 【百度地图API】如何在地图上添加标注?——另有:坐标拾取工具+打车费用接口介绍

    原文:[百度地图API]如何在地图上添加标注?--另有:坐标拾取工具+打车费用接口介绍 摘要: 在这篇文章中,你将学会,如何利用百度地图API进行标注.如何使用API新增的打车费用接口. ------ ...

  8. Java-继承特性

    继承的特点: 1.提高了代码的复用性. 2.让类与类之间发生了关系,有了这个关系,才有了多态的特性. (注意:千万不要为了获取其他类的功能,简化代码而继承:必须是类与类之间有所属关系才可以继承,所属关 ...

  9. 修改 dll

    由于没有源码,想改dll,就要依靠反汇编了. 输入 ildasm.exe 据说也可以直接 C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin 找到该软件 ...

  10. Sample Page

    This is an example page. It's different from a blog post because it will stay in one place and will ...