重学c#系列——缓存[盛派源码分析cache](九)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

重学c#系列——缓存[盛派源码分析cache](九)前⾔
以前整理过缓存的东西在:
只是粗略的例⼦,因为真的要去介绍缓存这个东西,要从内存开始,是⼀个有时间系列。

该⽂通过分析盛派源码,简单介绍如何实现⼀个简单的缓存机制。

正⽂
查看源码的出发点,我当时是这样想的,⽆论你采⽤哪种缓存,那么你都得暴露出⼀个object,让我可以进程增删改查吧。

在BaseContainer中,查看到:
/// <summary>
/// 获取符合当前缓存策略配置的缓存的操作对象实例
/// </summary>
protected static IBaseObjectCacheStrategy /*IBaseCacheStrategy<string,Dictionary<string, TBag>>*/ Cache
{
get
{
//使⽤⼯⼚模式或者配置进⾏动态加载
//return CacheStrategyFactory.GetContainerCacheStrategyInstance();
//以下代码可以实现缓存“热切换”,损失的效率有限。

如果需要追求极致效率,可以禁⽤type的判断
var containerCacheStrategy = ContainerCacheStrategyFactory.GetContainerCacheStrategyInstance()/*.ContainerCacheStrategy*/;
if (_containerCache == null || _containerCache.GetType() != containerCacheStrategy.GetType())
{
_containerCache = containerCacheStrategy;
}
if (_baseCache == null)
{
_baseCache = _baseCache ?? containerCacheStrategy.BaseCacheStrategy();
}
return _baseCache;
}
}
像这种属性,不⽤看肯定是单例了。

ContainerCacheStrategyFactory 是⼀个⽣产者,那么看下它到底⽣成了啥吧。

GetContainerCacheStrategyInstance:
public static IContainerCacheStrategy GetContainerCacheStrategyInstance()
{
//从底层进⾏判断
var containerCacheStrategy = CacheStrategyFactory.GetExtensionCacheStrategyInstance(ContainerCacheStrategyDomain.Instance)
as IContainerCacheStrategy;
return containerCacheStrategy;
}
ContainerCacheStrategyFactory 相当于是⼀⽚⽣产园container,CacheStrategyFactory是园区⾥⾯得⼯⼚,建筑学。

好的,那么就看⼀下CacheStrategyFactory这个⼯程到底⽣产了啥吧。

查看:ContainerCacheStrategyDomain.Instance
public class ContainerCacheStrategyDomain : ICacheStrategyDomain
{
#region 单例
/// <summary>
/// LocalCacheStrategy的构造函数
/// </summary>
ContainerCacheStrategyDomain() : base()
{
}
//静态LocalCacheStrategy
public static ICacheStrategyDomain Instance
{
get
{
return Nested.instance;//返回Nested类中的静态成员instance
}
}
class Nested
{
static Nested()
{
}
//将instance设为⼀个初始化的LocalCacheStrategy新实例
internal static readonly ContainerCacheStrategyDomain instance = new ContainerCacheStrategyDomain();
}
#endregion
private const string IDENTITY_NAME= "6526BBC0-718A-4F47-9675-D6DF6E1CE125";//固定值,请勿修改
private const string DOMAIN_NAME = "WeixinContainer";//固定值,请勿修改。

同时会作为缓存键命名空间的⼦级名称
public string IdentityName { get { return IDENTITY_NAME; } }
public string DomainName { get { return DOMAIN_NAME; } }
}
⾥⾯是⼀些固定值:
private const string IDENTITY_NAME= "6526BBC0-718A-4F47-9675-D6DF6E1CE125";//固定值,请勿修改
private const string DOMAIN_NAME = "WeixinContainer";//固定值,请勿修改。

同时会作为缓存键命名空间的⼦级名称
看到这种情况,可以想象到基本是和注册有关(注册服务)。

然后进GetExtensionCacheStrategyInstance看下:
/// <summary>
/// 获取指定领域缓存的换存策略
/// </summary>
/// <param name="cacheStrategyDomain">领域缓存信息(需要为单例)CacheStrategyDomain</param>
/// <returns></returns>
public static IDomainExtensionCacheStrategy GetExtensionCacheStrategyInstance(ICacheStrategyDomain cacheStrategyDomain)
{
return CacheStrategyDomainWarehouse.GetDomainExtensionCacheStrategy(GetObjectCacheStrategyInstance(), cacheStrategyDomain);
}
cacheStrategyDomain 是我们传进来得是⼀个实体类,后续猜测是⼀个注册标识对象。

GetObjectCacheStrategyInstance 看下这个⼲啥了。

/// <summary>
/// 注册当前全局环境下的缓存策略,并⽴即启⽤。

/// </summary>
/// <param name="func">如果为 null,将使⽤默认的本地缓存策略(LocalObjectCacheStrategy.Instance)</param>
public static void RegisterObjectCacheStrategy(Func<IBaseObjectCacheStrategy> func)
{
ObjectCacheStrateFunc = func;
if (func != null)
{
ObjectCacheStrategy = func();
}
}
/// <summary>
/// 获取全局缓存策略
/// </summary>
/// <returns></returns>
public static IBaseObjectCacheStrategy GetObjectCacheStrategyInstance()
{
if (ObjectCacheStrateFunc == null)
{
return LocalObjectCacheStrategy.Instance;
}
return ObjectCacheStrateFunc();
}
上⾯RegisterObjectCacheStrategy表⽰我们可以注册⼀种缓存策略,ObjectCacheStrateFunc 将会保存。

GetObjectCacheStrategyInstance 就是我们需要看的,如果我们没有注册得话,那么他就会⽤本地的缓存,LocalObjectCacheStrategy.Instance。

查看LocalObjectCacheStrategy.Instance是什么?
⾥⾯是⼀堆⽅法,设置key value 过期时间等。

不过我找到了这个:
static LocalObjectCacheHelper()
{
LocalObjectCache = HttpRuntime.Cache;
}
默认使⽤的是:HttpRuntime.Cache;
好的,那么参数我们都知道了,那么看下return CacheStrategyDomainWarehouse.GetDomainExtensionCacheStrategy(GetObjectCacheStrategyInstance(),
cacheStrategyDomain);中的GetDomainExtensionCacheStrategy⼲了啥吧。

/// <summary>
/// 获取领域缓存(指定特定的IBaseObjectCacheStrategy 缓存策略对象)
/// </summary>
/// <param name="baseObjectCacheStrategy">IBaseObjectCacheStrategy 缓存策略对象</param>
/// <param name="cacheStrategyDomain">缓存领域</param>
/// <returns></returns>
public static IDomainExtensionCacheStrategy GetDomainExtensionCacheStrategy(IBaseObjectCacheStrategy baseObjectCacheStrategy, ICacheStrategyDomain cacheStrategyDomain)
{
CacheStrategyDomainMappingCollection mappingCollection = GetMappingCollection(cacheStrategyDomain.IdentityName);
if (mappingCollection.ContainsKey(baseObjectCacheStrategy))
{
return ((Dictionary<IBaseObjectCacheStrategy, CacheStrategyDomainMappingItem>)mappingCollection)[baseObjectCacheStrategy].DomainExtensionCacheStrategy;
}
UnregisteredDomainCacheStrategyException ex = new UnregisteredDomainCacheStrategyException(cacheStrategyDomain.GetType(), baseObjectCacheStrategy.GetType());
SenparcTrace.BaseExceptionLog(ex);
throw ex;
}
上⾯的从代码表⾯意思就是去⼀个映射集合中更具identityName查找,如果没有的话就抛出异常,如果有的话,就返回注册过的对象。

/// <summary>
/// 获取某个领域内的所有CacheStrategyDomainMappingCollection
/// </summary>
/// <param name="identityName"></param>
/// <returns></returns>
private static CacheStrategyDomainMappingCollection GetMappingCollection(string identityName)
{
if (!_extensionCacheStrategyInstance.ContainsKey(identityName))
{
_extensionCacheStrategyInstance[identityName] = new CacheStrategyDomainMappingCollection();
}
return _extensionCacheStrategyInstance[identityName];
}
好吧,既然是这样那么肯定有注册啊。

找到注册:
/// <summary>
/// 注册领域缓存
/// </summary>
/// <param name="domainCacheStrategy"></param>
public static void RegisterCacheStrategyDomain(IDomainExtensionCacheStrategy domainCacheStrategy)
{
string identityName = domainCacheStrategy.CacheStrategyDomain.IdentityName;
IBaseObjectCacheStrategy key = domainCacheStrategy.BaseCacheStrategy();
CacheStrategyDomainMappingCollection mappingCollection = GetMappingCollection(identityName);
CacheStrategyDomainMappingItem cacheStrategyDomainMappingItem2 = ((Dictionary<IBaseObjectCacheStrategy, CacheStrategyDomainMappingItem>)mappingCollection)[key] = new CacheStrategyDomainMappingItem(domainCacheStrategy }
这⾥IDomainExtensionCacheStrategy ⾥⾯其实就是IBaseObjectCacheStrategy baseObjectCacheStrategy, ICacheStrategyDomain cacheStrategyDomain。

public interface IDomainExtensionCacheStrategy
{
/// <summary>
/// 领域缓存定义
/// </summary>
ICacheStrategyDomain CacheStrategyDomain
{
get;
}
/// <summary>
/// 使⽤的基础缓存策略
/// </summary>
Func<IBaseObjectCacheStrategy> BaseCacheStrategy
{
get;
}
/// <summary>
/// 向底层缓存注册当前缓存策略
/// </summary>
/// <param name="extensionCacheStrategy">扩展缓存策略实例</param>
void RegisterCacheStrategyDomain(IDomainExtensionCacheStrategy extensionCacheStrategy);
}
其实后⾯就是⼀个ioc了。


因为很多⼈没有去了解这个框架,也不需要了解这个框架,所以就不会发布到⾸页中。

相关文档
最新文档