[转载].Net通用基础框架(.Net Common Infrastructure)-缓存
- ASP.NET
- 2011-03-17
- 77热度
- 0评论
[转载].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
///
///
///
/// 键
/// 值
/// 持续时间
///
bool Add
///
///
void Clear();
///
///
///
/// 键
///
T Get
///
///
/// 键集合
///
IDictionary
///
///
/// 键 void Remove(string key);
///
///
///
/// 键
/// 值
///
bool Set
///
///
///
/// 键
/// 值
/// 持续时间
///
bool Set
}
}
[/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
{
return this.Add
}
public abstract bool Add
public abstract void Clear();
public abstract T Get
///
///
/// 键
///
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
public abstract void Remove(string key);
public bool Set
{
return this.Set
}
public abstract bool Set
}
}
[/csharp]
Aspnet缓存实现
[csharp]
using System;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Caching;
namespace Common.Cache
{
///
///
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
{
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
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
{
T result = default(T);
object value = this.cache.Get(this.GetFullName(key));
if (value is T)
{
result = (T)value;
}
return result;
}
public override IDictionary
{
IDictionary
foreach (string key in keys)
{
result.Add(key, this.Get
return result;
}
public override void Remove(string key)
{
this.cache.Remove(this.GetFullName(key));
}
public override bool Set public class MemcachedCache : CacheBase public override bool Add public override IDictionary return memcached.Get(fullKeys); public override void Remove(string key) public override bool Set public class CacheResultAdvice : IApplicationContextAware, IMethodInterceptor public IApplicationContext ApplicationContext /// /// 调用
/// return result; /// /// 调用
/// return result; /// /// 表达式
/// 上下文
/// 参数集合
/// return result;
{
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
{
///
///
{
private static MemcachedClient memcached = new MemcachedClient();
{
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
{
return memcached.Get
}
{
IEnumerable
}
{
memcached.Remove(this.GetFullName(key));
}
{
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
{
///
///
{
private IDictionary
{
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;
}
}
}
///
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
}
///
private bool IsMatch(IExpression expression, object context, IDictionary parameters)
{
bool result = expression == null;
if (!result)
{
result = (bool)expression.GetValue(result, parameters);
}
}
}
}
[/csharp]
测试时启动Common.Cache.ConsoleTest即可