一. 揭开迷雾

1. 程序集准备

  a.  需要给项目添加 System.Web 程序集。

  

b.  需要给使用的地方添加两个引用。

  

2. 程序集探究

     在对应的类中输入关键字 Cache,选中点击F12,查看Cache程序集,如下图所示:

我们一起来分析从上往下来分析一下该程序集。

(1). 两个字段,根据类型能看出来,一个是具体的时间点,另一个时间段,我们猜想,他们可能分别对应缓存中的绝对过期时间和相对过期时间。(其实事实也是如此)

  

(2). 构造函数

注意:通常我们实例化该类型的缓存,一般不直接通过构造函数实例化,我们通常使用 HttpRuntime.Cache 。我们一起来看看HttpRuntime的程序集,其中有个Cache属性,即可以通过它来获取Cache对象的实例。

  (3). 顾名思义通俗易懂的属性和方法。

   A : Count 属性,获取缓存个数。

B : Get(string key) 方法,根据缓存的键名来获取缓存的值。

C : Remove(string key) 方法,根据缓存的键名来删除缓存的值。

(4). 深究  public IDictionaryEnumerator GetEnumerator();

查看IDictionaryEnumerator的程序集,发现他是一个字典类型的集合,有键有值。

  那么问题来了,怎么遍历该字典类型的集合呢?怎么获取对应的键和值呢?F12查看 IEnumerator程序集,发现里面有一个MoveNext()方法,可以推进到集合的下一个元素。

(5).  Add和Insert方法,二者都为增加缓存的方法,而且二者最多参数的那个重载参数类型完全相同。不同的是Insert有多种重载方式,而Add只有一种重载。 二者核心差异:当缓存已经存在,用Add添加会报错,但用Insert添加,会直接覆盖更新。

下面以Add为例,一起来分析这七个参数。

A:key: 代表缓存的键名。

B:value:代表缓存的值,可以是任意类型。

C:dependencies:表示缓存的依赖项,可以依赖文件、文件夹、多个文件、以及依赖数据库,如果不需要依赖时,传入参数null。

D:absoluteExpiration:代表绝对过期时间,是个DateTime类型的时间点。如果要启用绝对过期时间,那么slidingExpriation必须为:Cache.NoSlidingExpiration。

     该参数表现形式可以是:如:DateTime.Now.AddDays(1);   DateTime.Parse("2016-5-28 20:32:00")  。

E:slidingExpiration:代表相对过期时间,是个TimeSpan类型的时间段。   如果要启用相对过期时间,那么absoluteExpiration必须为:Cache.NoAbsoluteExpiration。

该参数的表现形式可以是:: 如:new TimeSpan(0,0, 0, 2) 天,小时,分钟,秒   。

F:priority:代表缓存销毁时的移除顺序,优先级低的先销毁。没有特殊要求通常使用: CacheItemPriority.Normal  即可。

G:onRemoveCallBack:是一个无返回值具有三个参数的委托。public delegate void CacheItemRemovedCallback(string key, object value, CacheItemRemovedReason reason);

当缓存过期时,调用该委托。委托的三个参数分别代表的含义为:缓存的键、缓存的值、缓存销毁的原因。

二. 缓存封装

 1.  封装思路

  首先我们要清楚,封装的目的是什么? 说白了,方便自己、方便别人的灵活调用;同时便于以后的代码维护,能应对需求的变更。

通常调用的方式有两种:1. 将方法写成static静态方法,直接通过   类名.方法名  来进行调用。(该种方式偏离了面向对象的体系)

2. 将该类实例化,然后用实例化的对象调用该类中的封装方法。

3. 这里暂时不考虑 IOC的方式创建对象。

我们试想,会有什么需求变化呢? 有一天,PM要求,所有使用System.Web.Caching.Cache缓存的地方,都要改成 MemoryCache,如果我们事先没有应对措施,我的天!数不胜数的方法中均是传入的 Cache实例,不支持MemoryCache的实例,排着改?保证你崩溃!!!!!

上述场景,在实际开发中非常常见,解决该问题,我们通常使用DIP原则进行封装(依赖倒置原则,核心面向接口编程)。

  所以我们定义一个缓存接口ICache,约束了缓存的定义的规范,然后我们再建立一个 RuntimeCacheHelp 类,对ICache进行了实现,同时也定义自己特有的方法。

 2.  话不多说,直接上代码。

  接口:

     /// <summary>
/// 定义缓存接口
/// </summary>
public interface ICache
{
//1.缓存的个数只能获取,不能设置
int Count { get; }
//2. 删除特定键的缓存
void Remove(string key);
//3.移除全部缓存
void RemoveAll();
//4.根据键值获取特定类型的缓存
T Get<T>(string key);
//5.判断缓存是否存在
bool Contains(string key);
//6. 获取缓存值的类型
Type GetCacheType(string key);
//7. 增加或更新缓存(存在则更新,不存在则添加,采用绝对时间的模式)
/// <param name="cacheTime">绝对过期时间,默认1天</param>
void AddOrUpdate(string key, object value,int cacheTime=); }

  缓存帮助类:

 /// <summary>
/// HttpRuntime缓存
/// 需要引入:System.Web程序集
/// 支持缓存依赖
/// </summary>
public class RuntimeCacheHelp : ICache
{
//一.实例化的两种方式 #region 1.封装成属性
protected Cache cache
{
get
{
return HttpRuntime.Cache;
}
}
#endregion #region 2.利用构造函数 //public Cache cache2 { get; set; }
//public RuntimeCacheHelp()
//{
// cache2 = HttpRuntime.Cache;
//}
#endregion //二. 实现接口中的方法 #region 1.获取缓存的个数
public int Count
{
get { return cache.Count; }
}
#endregion #region 2.删除特定键的缓存
/// <summary>
/// 删除特定键的缓存
/// </summary>
/// <param name="key">缓存的键名</param>
public void Remove(string key)
{
cache.Remove(key);
}
#endregion #region 3.移除全部缓存
/// <summary>
/// 移除全部缓存
/// </summary>
public void RemoveAll()
{
IDictionaryEnumerator CacheEnum = cache.GetEnumerator();
while (CacheEnum.MoveNext())
{
cache.Remove(CacheEnum.Key.ToString());
}
} #endregion #region 4.根据键值获取特定类型的缓存
/// <summary>
/// 根据键值获取特定类型的缓存
/// </summary>
/// <typeparam name="T">泛型T</typeparam>
/// <param name="key">键名</param>
/// <returns></returns>
public T Get<T>(string key)
{
//程序集中 this属性的应用
if (cache[key] != null)
{
return (T)cache[key];
}
return default(T);
}
#endregion #region 5.判断缓存是否存在
/// <summary>
/// 判断缓存是否存在
/// </summary>
/// <param name="key">键值</param>
/// <returns>true代表存在;false代表不存在</returns>
public bool Contains(string key)
{
return cache.Get(key) == null ? false : true;
} #endregion #region 6.获取缓存值的类型(子类创建)
/// <summary>
/// 获取缓存值的类型
/// </summary>
/// <param name="key">键名</param>
/// <returns>键名对应的缓存值的类型</returns>
public Type GetCacheType(string key)
{
return cache[key].GetType();
}
#endregion #region 7.增加或更新缓存(存在则更新,不存在则添加,采用绝对时间的模式)
/// <summary>
/// 增加或更新缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="cacheTime">绝对过期时间,默认为1天</param>
public void AddOrUpdate(string key, object value, int cacheTime = )
{
var absoluteTime = DateTime.Now + TimeSpan.FromDays(cacheTime);
cache.Insert(key, value, null, absoluteTime, Cache.NoSlidingExpiration);
} #endregion //三. 子类创建的新方法 #region 1.获取全部缓存(子类创建)
public IDictionaryEnumerator GetAllCache()
{
IDictionaryEnumerator cacheList = cache.GetEnumerator();
//获取键值的方法
//while (cacheList.MoveNext())
//{
// var key = cacheList.Key.ToString();
// var value = cacheList.Value;
//}
return cacheList;
}
#endregion #region 2.Add模式增加缓存(子类创建)
/// <summary>
/// Add模式增加缓存(如果该缓存已经存在,再次添加会报错;Insert模式会覆盖上次)
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="absoluteExpiration">绝对过期时间的参数:如:DateTime.Now.AddDays(1); DateTime.Parse("2016-5-28 20:32:00");</param>
/// <param name="slidingExpiration">相对过期时间的参数: 如:new TimeSpan(0,0, 0, 2) 天,小时,分钟,秒</param>
/// <param name="isAbsolute">true代表使用绝对过期时间,填写absoluteExpiration参数,slidingExpiration忽略不需要填写
/// false代表使用绝对过期时间,填写slidingExpiration 参数, absoluteExpiration忽略不需要填写
/// </param>
/// <param name="dependencies">缓存依赖:可以依赖文件、文件夹、数据库表</param>
/// <param name="priority">缓存销毁时的优先级,没有特别要求,使用该封装的默认即可</param>
/// <param name="onRemoveCallback">缓存失效后的回调:含有三个参数的委托,三个参数分别为(key,value,reason) 即(缓存的键、值、失效原因)</param>
public void AddCache(string key, object value, DateTime absoluteExpiration, TimeSpan slidingExpiration, bool isAbsolute = true, CacheDependency dependencies = null,
CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback onRemoveCallback = null)
{
if (isAbsolute)
{
//绝对过期
cache.Add(key, value, dependencies, absoluteExpiration, Cache.NoSlidingExpiration, priority, onRemoveCallback);
}
else
{
//相对过期
cache.Add(key, value, dependencies, Cache.NoAbsoluteExpiration, slidingExpiration, priority, onRemoveCallback);
}
}
#endregion #region 3.Insert模式增加缓存(子类创建)
/// <summary>
/// Insert模式增加缓存(如果该缓存已经存在,会覆盖上次,Add模式则是报错)
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="absoluteExpiration">绝对过期时间的参数:如:DateTime.Now.AddDays(1); DateTime.Parse("2016-5-28 20:32:00");</param>
/// <param name="slidingExpiration">相对过期时间的参数: 如:new TimeSpan(0,0, 0, 2) 天,小时,分钟,秒</param>
/// <param name="isAbsolute">true代表使用绝对过期时间,填写absoluteExpiration参数,slidingExpiration忽略不需要填写
/// false代表使用绝对过期时间,填写slidingExpiration 参数, absoluteExpiration忽略不需要填写
/// </param>
/// <param name="dependencies">缓存依赖:可以依赖文件、文件夹、数据库表</param>
/// <param name="priority">缓存销毁时的优先级,没有特别要求,使用该封装的默认即可</param>
/// <param name="onRemoveCallback">缓存失效后的回调:含有三个参数的委托,三个参数分别为(key,value,reason) 即(缓存的键、值、失效原因)</param>
public void InsertCache(string key, object value, DateTime absoluteExpiration, TimeSpan slidingExpiration, bool isAbsolute = true, CacheDependency dependencies = null,
CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback onRemoveCallback = null)
{
if (isAbsolute)
{
//绝对过期
cache.Insert(key, value, dependencies, absoluteExpiration, Cache.NoSlidingExpiration, priority, onRemoveCallback);
}
else
{
//相对过期
cache.Insert(key, value, dependencies, Cache.NoAbsoluteExpiration, slidingExpiration, priority, onRemoveCallback);
}
}
#endregion

  3. 如何调用?调用过程中会存在哪些问题?我们再后续章节中进行介绍。

第一节:从程序集的角度分析System.Web.Caching.Cache ,并完成基本封装。的更多相关文章

  1. System.Web.Caching.Cache类 缓存 各种缓存依赖

    原文:System.Web.Caching.Cache类 缓存 各种缓存依赖 Cache类,是一个用于缓存常用信息的类.HttpRuntime.Cache以及HttpContext.Current.C ...

  2. System.Web.Caching.Cache类 缓存 各种缓存依赖(转)

    转自:http://www.cnblogs.com/kissdodog/archive/2013/05/07/3064895.html Cache类,是一个用于缓存常用信息的类.HttpRuntime ...

  3. System.Web.Caching.Cache类 Asp.Net缓存 各种缓存依赖

    Cache类,是一个用于缓存常用信息的类.HttpRuntime.Cache以及HttpContext.Current.Cache都是该类的实例. 一.属性 属性 说明 Count 获取存储在缓存中的 ...

  4. C# System.Web.Caching.Cache类 缓存 各种缓存依赖

    原文:https://www.cnblogs.com/kissdodog/archive/2013/05/07/3064895.html Cache类,是一个用于缓存常用信息的类.HttpRuntim ...

  5. System.Web.Caching.Cache类 缓存

    1.文件缓存依赖 public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender ...

  6. System.Web.Caching.Cache 方法汇总

    在做后台的时候,想着把所有栏目放到缓存里,就这里了一个类.必然是有缺陷,暂时没有实现滑动缓存 using System; using System.Collections; using System. ...

  7. 清除 System.Web.Caching.Cache 以"xxx"开头的缓存

    public static void ClearStartCache(string keyStart) { List<string> cacheKeys = new List<str ...

  8. System.Web.Caching.Cache缓存帮助类

    /// <summary> /// 缓存帮助类 /// </summary> public class CacheHelper { /// <summary> // ...

  9. 缓存-System.Web.Caching.Cache

    实现 Web 应用程序的缓存. 每个应用程序域创建一个此类的实例,只要应用程序域将保持活动状态,保持有效. 有关此类的实例的信息,请通过Cache的属性HttpContext对象或Cache属性的Pa ...

随机推荐

  1. Jmeter 常用断言使用

    响应断言 可根据要测试响应字段和模式匹配规则来设置断言,比如下方截图是匹配返回的结果中是否包含"code:200,",如果包含则表示断言成功,否则失败.响应断言可添加多个,但是多个 ...

  2. PSexec以及xcopy的简单使用

    1. 远程执行命令. 有时候不想远程但是想执行一些命令, 比较简单的方法是: 下载systeminternals 然后解压缩后可以讲目录放到path环境变量中 然后打开命令行工具 输入 如下的命令 p ...

  3. Linux下DB2命令学习及整理

    DB2相关数据库命令 1.数据库实例的启动首先要启动数据库的实例,即切换到db2inst1用户(注:db2inst1用户为当前数据库的实例),然后执行db2start启动数据库的实例 [root@lo ...

  4. 删除Mac上的mysql数据库

    sudo rm /usr/local/mysqlsudo rm -rf /usr/local/mysql*sudo rm -rf /Library/StartupItems/MySQLCOMsudo ...

  5. PHP的安装,编译,扩展工具

    1.基本容易混淆的概念 pecl php的社区贡献扩展库,全称为PHP Extension Community Library, 是php的底层库, 使用C语言编写 pear php的应用扩展库,全称 ...

  6. 核化主成分分析(Kernel PCA)应用及调参

    核化这个概念在很多机器学习方法中都有应用,如SVM,PCA等.在此结合sklearn中的KPCA说说核函数具体怎么来用. KPCA和PCA都是用来做无监督数据处理的,但是有一点不一样.PCA是降维,把 ...

  7. 荣耀实锤Magic2或将助力AI,再次带动成长?

    临近年底,热闹了一年的手机圈纷纷偃旗息鼓,准备为明年3月的新品发力.然而今天(12月7日),恰逢节气大雪,@荣耀手机 在微博发布了一张预热海报,随后荣耀总裁赵明转发这条微博表示「关于技术,真的有很多话 ...

  8. 使用TortoiseSVN创建版本库

    1. 使用TortoiseSVN创建版本库 在SVN中,为了便于创建分支和标签,我们习惯于将Repository版本库的结构布置为:/branches,/tags,/trunk.分别代表分支,标签以及 ...

  9. BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】

    题目分析: 很无聊的一道题目.首先区间内单点对应异或值的询问容易想到trie树.由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问.case2维护dfs序,对d ...

  10. MT【58】反演圆和极线极点和谐统一

    解答:如图 评:1.反演圆及其性质介绍: 评2:此题的源头是1995年全国卷压轴题,这里用极线极点的相关性质也可以处理: 注:用相关点法很容易得到轨迹.