[转载].Net通用基础框架(.Net Common Infrastructure)-缓存

[转载].Net通用基础框架(.Net Common Infrastructure)-缓存 - 张艺聍 - 博客园.

缓存可以提高网站性能,减轻数据库压力。网站中常用的缓存分为业务数据缓存和页面文件缓存两类,其中业务数据缓存常用AspnetCache,Memcached等,而页面文件缓存常用Squid和Nginx,今天 介绍的内容是业务数据缓存。

  • Common.Cache类图

  • 缓存接口ICache:使用Add方法时,如果key存在,则返回false。使用Set方法时,key不存在则添加,否则更新。

[csharp]
using System;
using System.Collections.Generic;

namespace Common.Cache
{
///

/// 缓存
///

public interface ICache
{
///

/// 增加
///

/// 类型
/// 键 /// 值 /// 结果
bool Add(string key, T value);

///

/// 增加
///

/// 类型
/// 键 /// 值 /// 持续时间 /// 结果
bool Add(string key, T value, TimeSpan duration);

///

/// 清除
///

void Clear();

///

/// 获取
///

/// 类型
/// 键 ///
T Get(string key);

///

/// 多线程获取
///

/// 键集合 /// 值集合
IDictionary MultiGet(IList keys);

///

/// 移除
///

/// 键 void Remove(string key);

///

/// 设置
///

/// 类型
/// 键 /// 值 /// 结果
bool Set(string key, T value);

///

/// 设置
///

/// 类型
/// 键 /// 值 /// 持续时间 /// 结果
bool Set(string key, T value, TimeSpan duration);
}
}

[/csharp]
缓存基类
[csharp]
using System;
using System.Collections.Generic;

namespace Common.Cache
{
///

/// 缓存基类
///

public abstract class CacheBase : ICache
{
private TimeSpan maxDuration = TimeSpan.FromDays(15);

///

/// 最长持续时间
///

public TimeSpan MaxDuration
{
get
{
return this.maxDuration;
}
set
{
this.maxDuration = value;
}
}

///

/// 前缀
///

public string Prefix
{
get;
set;
}

public bool Add(string key, T value)
{
return this.Add(key, value, this.MaxDuration);
}

public abstract bool Add(string key, T value, TimeSpan duration);

public abstract void Clear();

public abstract T Get(string key);

///

/// 获取全名
///

/// 键 /// 全名
public virtual string GetFullName(string key)
{
string result = key;
if (!string.IsNullOrWhiteSpace(this.Prefix))
{
result = string.Format("{0}.{1}", this.Prefix, key);
}

return result;
}

public abstract IDictionary MultiGet(IList keys);

public abstract void Remove(string key);

public bool Set(string key, T value)
{
return this.Set(key, value, this.MaxDuration);
}

public abstract bool Set(string key, T value, TimeSpan duration);
}
}
[/csharp]
Aspnet缓存实现
[csharp]
using System;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Caching;

namespace Common.Cache
{
///

/// Aspnet缓存
///

public class AspnetCache : CacheBase
{
private System.Web.Caching.Cache cache = HttpRuntime.Cache;

///

/// 构造函数
///

public AspnetCache()
: this("Common.Cache")
{

}

///

/// 构造函数
///

/// 前缀 public AspnetCache(string prefix)
{
this.Prefix = prefix;
}

public override bool Add(string key, T value, TimeSpan duration)
{
bool result = false;
if (value != null)
{
if (duration <= TimeSpan.Zero) { duration = this.MaxDuration; } result = this.cache.Add(this.GetFullName(key), value, null, DateTime.Now.Add(duration), System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Default, null) == null; } return result; } public override void Clear() { // 获取键集合 IList keys = new List();
IDictionaryEnumerator caches = this.cache.GetEnumerator();
while (caches.MoveNext())
{
string key = caches.Key.ToString();
if (key.StartsWith(this.Prefix))
{
keys.Add(key);
}
}
// 移除全部
foreach (string key in keys)
{
this.cache.Remove(key);
}
}

public override T Get(string key)
{
T result = default(T);
object value = this.cache.Get(this.GetFullName(key));
if (value is T)
{
result = (T)value;
}

return result;
}

public override IDictionary MultiGet(IList keys)
{
IDictionary result = new Dictionary();
foreach (string key in keys)
{
result.Add(key, this.Get(key));
}

return result;
}

public override void Remove(string key)
{
this.cache.Remove(this.GetFullName(key));
}

public override bool Set(string key, T value, TimeSpan duration)
{
bool result = false;
if (value != null)
{
if (duration <= TimeSpan.Zero) { duration = this.MaxDuration; } this.cache.Insert(this.GetFullName(key), value, null, DateTime.Now.Add(duration), System.Web.Caching.Cache.NoSlidingExpiration); result = true; } return result; } } } [/csharp] Memcached分布式缓存实现:EnyimMemcached客户端中实现了一致性哈希算法 [csharp] using System; using System.Collections.Generic; using System.Linq; using Enyim.Caching; using Enyim.Caching.Memcached; namespace Common.Cache { ///

/// Memcached缓存
///

public class MemcachedCache : CacheBase
{
private static MemcachedClient memcached = new MemcachedClient();

public override bool Add(string key, T value, TimeSpan duration)
{
if (duration <= TimeSpan.Zero) { duration = this.MaxDuration; } return memcached.Store(StoreMode.Add, this.GetFullName(key), value, duration); } public override void Clear() { memcached.FlushAll(); } public override T Get(string key)
{
return memcached.Get(this.GetFullName(key));
}

public override IDictionary MultiGet(IList keys)
{
IEnumerable fullKeys = keys.Select(k => this.GetFullName(k));

return memcached.Get(fullKeys);
}

public override void Remove(string key)
{
memcached.Remove(this.GetFullName(key));
}

public override bool Set(string key, T value, TimeSpan duration)
{
if (duration <= TimeSpan.Zero) { duration = this.MaxDuration; } return memcached.Store(StoreMode.Set, this.GetFullName(key), value, duration); } } } [/csharp] 缓存结果通知:实现了Spring.Aop中的IMethodInterceptor接口,用Spring的表达式解析得出key的值,使用时在方法上打特性标签,如Common.Mom项目中用到的[CacheResult(CacheName = "Aspnet", Key = "'Cmr.Dsr.GetSubscriber.' + #id", TimeToLive = "0:5:0")] [csharp] using System.Collections; using System.Collections.Generic; using System.Reflection; using AopAlliance.Intercept; using Spring.Caching; using Spring.Context; using Spring.Expressions; namespace Common.Cache.Aspects { ///

/// 缓存结果通知
///

public class CacheResultAdvice : IApplicationContextAware, IMethodInterceptor
{
private IDictionary cacheResults = new Dictionary();

public IApplicationContext ApplicationContext
{
get;
set;
}

///

/// 获取缓存结果
///

/// 调用 /// 缓存结果
private CacheResultAttribute GetCacheResult(IMethodInvocation invocation)
{
CacheResultAttribute result = null;
MethodInfo method = invocation.Method;
if (this.cacheResults.ContainsKey(method))
{
result = this.cacheResults[method];
}
if (result == null)
{
object[] attributes = method.GetCustomAttributes(typeof(CacheResultAttribute), false);
if (attributes.Length > 0)
{
result = (CacheResultAttribute)attributes[0];
this.cacheResults[method] = result;
}
}

return result;
}

///

/// 获取参数集合
///

/// 调用 /// 参数集合
private IDictionary GetParameters(IMethodInvocation invocation)
{
IDictionary result = new Hashtable();
MethodInfo method = invocation.Method;
object[] arguments = invocation.Arguments;
ParameterInfo[] parameters = method.GetParameters();
for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameter = parameters[i]; result[parameter.Name] = arguments[i]; } return result; } public object Invoke(IMethodInvocation invocation) { object result = null; IDictionary parameters = this.GetParameters(invocation); CacheResultAttribute cacheResult = this.GetCacheResult(invocation); if (cacheResult != null && cacheResult.KeyExpression != null) { string key = cacheResult.KeyExpression.GetValue(null, parameters).ToString(); if (!string.IsNullOrEmpty(key)) { ICache cache = this.ApplicationContext.GetObject(cacheResult.CacheName) as ICache; if (cache != null) { result = cache.Get(key);
if (result == null)
{
result = invocation.Proceed();
if (this.IsMatch(cacheResult.ConditionExpression, result, parameters))
{
cache.Set(key, result, cacheResult.TimeToLiveTimeSpan);
}
}
}
}
}
if (result == null)
{
result = invocation.Proceed();
}

return result;
}

///

/// 是否匹配
///

/// 表达式 /// 上下文 /// 参数集合 /// 结果
private bool IsMatch(IExpression expression, object context, IDictionary parameters)
{
bool result = expression == null;
if (!result)
{
result = (bool)expression.GetValue(result, parameters);
}

return result;
}
}
}
[/csharp]
测试时启动Common.Cache.ConsoleTest即可

评论区未打开,无法接收留言!
基于Wordpress. Theme By Document. ICP备案号 ICP备10086号