源代碼:https://git.oschina.net/zhaord/CacheDemo.git(dev_redis 分支)
前提:已安裝并運(yùn)行redis服務(wù)器
redis 緩存
通過 《C# 緩存》 可以了解到,緩存其實(shí),就是一系列的 key-value,而 redis 是典型的key-value數(shù)據(jù)庫(kù)之一,那么,我們是不是可以借助 redis來(lái)實(shí)現(xiàn)緩存呢?答案是肯定的!
實(shí)現(xiàn)
代碼是在 《C# 緩存》基礎(chǔ)上修改的,代碼分支為:dev_redis。
在 《C# 緩存》中,是用C#自帶的類庫(kù)實(shí)現(xiàn)的緩存,那么,我們只要繼承自 cachebase,并重寫相關(guān)方法,就可以實(shí)現(xiàn)使用redis作為緩存服務(wù)器,在實(shí)現(xiàn)之前,我們先約定key值為 “n:name,c:key”來(lái)作為redis的key值,啟用name為自定義的,因?yàn)榭赡懿煌姆謱訒?huì)使用不同的name名稱,key就是需要保存的緩存項(xiàng)的key,代碼如下
protected virtual string GetLocalizedKey(string key)
{
return "n:" + "RandomRedis" + ",c:" + key;
}
redis中保存的value值,格式是 "類名,程序集名 | 序列化后的值" 作為value的保存格式,具體實(shí)現(xiàn)代碼如下
protected virtual string Serialize(object value, Type type)
{
var serialized = JsonConvert.SerializeObject(value);
return string.Format(
"{0}{1}{2}",
type.AssemblyQualifiedName,
TypeSeperator,
serialized
);
}
既然,我們針對(duì)保存的值進(jìn)行了格式約定,那么久需要解析約定,解析代碼如下
protected virtual object Deserialize(RedisValue objbyte)
{
var serializedObj = objbyte.ToString();
var typeSeperatorIndex = serializedObj.IndexOf(TypeSeperator);
var type = Type.GetType(serializedObj.Substring(0, typeSeperatorIndex));
var serialized = serializedObj.Substring(typeSeperatorIndex + 1);
return JsonConvert.DeserializeObject(serialized, type);
}
通過以上兩個(gè)函數(shù),我們可以顯示取值和設(shè)置值得函數(shù),如下
public override object GetOrDefault(string key)
{
var objbyte = this._database.StringGet(this.GetLocalizedKey(key));
return objbyte.HasValue ? this.Deserialize(objbyte) : null;
}
public override void Set(string key, object value, TimeSpan? slidingExpireTime = null, TimeSpan? absoluteExpireTime = null)
{
if (value == null)
{
throw new Exception("不可以插入null到緩存!");
}
var type = value.GetType();
// 以string類型保存緩存值
this._database.StringSet(
this.GetLocalizedKey(key),
this.Serialize(value, type),
absoluteExpireTime ?? slidingExpireTime ?? TimeSpan.FromSeconds(60)
);
}
那么整個(gè)緩存實(shí)現(xiàn)的代碼如下
public class RedisCache
:CacheBase
{
private readonly IDatabase _database;
private ConnectionMultiplexer redisClient = ConnectionMultiplexer.Connect("localhost");
private const char TypeSeperator = '|';
public RedisCache()
{
this._database = this.redisClient.GetDatabase();
}
public override object GetOrDefault(string key)
{
var objbyte = this._database.StringGet(this.GetLocalizedKey(key));
return objbyte.HasValue ? this.Deserialize(objbyte) : null;
}
public override void Set(string key, object value, TimeSpan? slidingExpireTime = null, TimeSpan? absoluteExpireTime = null)
{
if (value == null)
{
throw new Exception("不可以插入null到緩存!");
}
var type = value.GetType();
// 以string類型保存緩存值
this._database.StringSet(
this.GetLocalizedKey(key),
this.Serialize(value, type),
absoluteExpireTime ?? slidingExpireTime ?? TimeSpan.FromSeconds(60)
);
}
public override void Remove(string key)
{
this._database.KeyDelete(this.GetLocalizedKey(key));
}
public override void Clear()
{
this._database.KeyDeleteWithPrefix(this.GetLocalizedKey("*"));
}
protected virtual object Deserialize(RedisValue objbyte)
{
var serializedObj = objbyte.ToString();
var typeSeperatorIndex = serializedObj.IndexOf(TypeSeperator);
var type = Type.GetType(serializedObj.Substring(0, typeSeperatorIndex));
var serialized = serializedObj.Substring(typeSeperatorIndex + 1);
return JsonConvert.DeserializeObject(serialized, type);
}
protected virtual string Serialize(object value, Type type)
{
var serialized = JsonConvert.SerializeObject(value);
return string.Format(
"{0}{1}{2}",
type.AssemblyQualifiedName,
TypeSeperator,
serialized
);
}
protected virtual string GetLocalizedKey(string key)
{
return "n:" + "RandomRedis" + ",c:" + key;
}
}
代碼大部分實(shí)現(xiàn),是和democache類想通,只不過,democache通過封裝memory實(shí)現(xiàn)緩存保存,而 類 RedisCache 封裝 redis客戶端,作為緩存 容器!
使用緩存
在《C# 緩存》 已經(jīng)寫好了測(cè)試過程,我們只需要將代碼ICache cache = new DemoCache(); 替換為 ICache cache = new RedisCache();即可使用新的緩存實(shí)現(xiàn)方式。
運(yùn)行結(jié)果
具體的運(yùn)行結(jié)果如下

和 《C# 緩存》 中運(yùn)行期望一直,說(shuō)明我們已經(jīng)成功使用redis來(lái)作為緩存容器了!
總結(jié)
通過上述描述,我們就可以借助redis來(lái)實(shí)現(xiàn)緩存容器了。
本片文章和《C# 緩存》中使用了大量ABP的代碼。
qq:1260825783
轉(zhuǎn)載備注:http://www.itdecent.cn/p/f5f2a5e7ec1c