Orchard源码分析(4.4):Orchard.Caching.CacheModule类
2016-03-26 12:10
483 查看
概述
CacheModule也是一个Autofac模块。
一、CacheModule类
CacheModule将DefaultCacheManager注册为ICacheManager:
[align=left] public class CacheModule : Module {[/align]
[align=left] protected override void Load( ContainerBuilder builder) {[/align]
[align=left] builder.RegisterType<DefaultCacheManager>()[/align]
[align=left] .As< ICacheManager>()[/align]
[align=left] .InstancePerDependency();[/align]
[align=left] }[/align]
[align=left] //...[/align]
[align=left] }[/align]
如果类有一个接受ICacheManager型的参数的构造函数,Autofac容器在解析(Resolve)该类生成对象之前,会先解析一个ICacheManager型对象作为参数:
[align=left] public class CacheModule : Module {[/align]
[align=left] //...[/align]
[align=left] protected override void AttachToComponentRegistration(Autofac.Core. IComponentRegistry componentRegistry, Autofac.Core.IComponentRegistration registration) {[/align]
[align=left] var needsCacheManager = registration.Activator.LimitType[/align]
[align=left] .GetConstructors()[/align]
[align=left] .Any(x => x.GetParameters()[/align]
[align=left] .Any(xx => xx.ParameterType == typeof(ICacheManager )));[/align]
[align=left] [/align]
[align=left] if (needsCacheManager) {[/align]
[align=left] registration.Preparing += (sender, e) => {[/align]
[align=left] var parameter = new TypedParameter([/align]
[align=left] typeof(ICacheManager ),[/align]
[align=left] e.Context.Resolve< ICacheManager>(new TypedParameter( typeof(Type ), registration.Activator.LimitType)));[/align]
[align=left] e.Parameters = e.Parameters.Concat( new[] { parameter });[/align]
[align=left] };[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
Cache Manager是与类型相关的,这实际上是CacheModule存在的意义所在。比如Orchard.Environment.DefaultOrchardHost和其他类型不会共享同一个DefaultCacheManager对象。
二、DefaultCacheManager:ICacheManager类
DefaultCacheManager类公开了两个方法:
[align=left] public ICache <TKey, TResult> GetCache<TKey, TResult>() {[/align]
[align=left] return _cacheHolder.GetCache<TKey, TResult>(_component);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public TResult Get<TKey, TResult>(TKey key, Func< AcquireContext<TKey>, TResult> acquire) {[/align]
[align=left] return GetCache<TKey, TResult>().Get(key, acquire);[/align]
[align=left] }[/align]
第 一个方法可以获取类型相关的ICache<TKey,TResult>(Cache<TKey,TResult>)对象集合;第 二个方法通过Key值获取具体的某一个Cache Result,即实际的缓存值。Cache<TKey,TResult>会在下面介绍。
不难看出,DefaultCacheManager是对ICacheHolder的简单封装,就算没有DefaultCacheManager类,也可以不怎么方便地使用缓存机制,因为实际的缓存存取是交给ICacheHolder来处理的,默认使用的是DefaultCacheHolder,这是一个应用程序域级的单例。
三、DefaultCacheHolder:ICacheHolder类
绝大多数的缓存机制都是采用字典的形式,DefaultCacheHolder中使用线程安全的ConcurrentDictionary<CacheKey, object>型字典来保存缓存,这里称为类型缓存字典,注意该字典中并不存储实际的缓存值。为了方便,在这里我们把CacheKey称为类型缓存字典Key;object称为类型缓存字典Value, 实际类型为泛型Cache<TKey,TResult>:ICache<TKey,TResult>的封闭类型。 Cache<TKey,Result>内部也有一个字典,类型为ConcurrentDictionary<TKey, CacheEntry>。在这里,TKey称为缓存字典Key,CacheEntry称为缓存字典Value。
CacheEntry有一个类型为TResult名为Result的属性,这里称为缓存Result,这才是实际的缓存值。
在分析源码的时候要特别区分这些我们约定的概念:
1、类型缓存字典、类型缓存字典Key、类型缓存字典Value
2、缓存字典、缓存字典Key、缓存字典Value和缓存Result。
在使用缓存时,我们是通过"缓存字典Key"来获取一个"缓存Result"。
DefaultCacheHolder仅公开了一个GetCache方法:
[align=left] public ICache<TKey, TResult> GetCache<TKey, TResult>(Type component) {[/align]
[align=left] var cacheKey = new CacheKey(component, typeof(TKey), typeof (TResult));[/align]
[align=left] var result = _caches.GetOrAdd(cacheKey, k => new Cache<TKey, TResult>(_cacheContextAccessor));[/align]
[align=left] return (Cache <TKey, TResult>)result;[/align]
[align=left] }[/align]
方法首先使用两个泛型参数的类型加上一个方法参数(Type型),可以构成一个CacheKey。CacheKey是一个三元组:
[align=left] class CacheKey : Tuple<Type, Type , Type> {[/align]
[align=left] public CacheKey(Type component, Type key, Type result)[/align]
[align=left] : base(component, key, result) {[/align]
[align=left] }[/align]
[align=left] }[/align]
然后从类型缓存字典中获取一个Cache<TKey, TResult>:ICache<TKey,TResult>对象。这时可以认为获取了一个类型相关的缓存字典。调用Cache<TKey, TResult>对象Get方法获取实际的缓存值。
DefaultCacheHolder 采用延迟缓存机制,在第一次从缓存中获取对象时才会去构建对象;提供可扩展的缓存到期、更新策略,比如使用Orchard.Services.Clock 类配合可以让缓存在某个具体的时间到期或一定时间间隔到期。缓存过期并不表示它在内存中被立即销毁,而是会在下一次尝试获取缓存的时候重新生成缓存。
相关类型(皆在Orchard.Caching命名空间下):
DefaultCacheManager : ICacheManager
DefaultCacheHolder : ICacheHolder
DefaultCacheContextAccessor : ICacheContextAccessor
DefaultParallelCacheContext : IParallelCacheContext
DefaultAsyncTokenProvider : IAsyncTokenProvider
AcquireContext<TKey>:IAcquireContext
SimpleAcquireContext : IAcquireContext
Signals : ISignals : IVolatileProvider : ISingletonDependency
Signals.Token : IVolatileToken(Private nested class)
Cache<TKey, TResult> : ICache<TKey, TResult>
CacheEntry(Private class)
Weak<T>
参考资料:
Autofac:Structuring With Modules
Autofac:Activation events
http://skywalkersoftwaredevelopment.net/orchard-development/api/autofac-module
CacheModule也是一个Autofac模块。
一、CacheModule类
CacheModule将DefaultCacheManager注册为ICacheManager:
[align=left] public class CacheModule : Module {[/align]
[align=left] protected override void Load( ContainerBuilder builder) {[/align]
[align=left] builder.RegisterType<DefaultCacheManager>()[/align]
[align=left] .As< ICacheManager>()[/align]
[align=left] .InstancePerDependency();[/align]
[align=left] }[/align]
[align=left] //...[/align]
[align=left] }[/align]
如果类有一个接受ICacheManager型的参数的构造函数,Autofac容器在解析(Resolve)该类生成对象之前,会先解析一个ICacheManager型对象作为参数:
[align=left] public class CacheModule : Module {[/align]
[align=left] //...[/align]
[align=left] protected override void AttachToComponentRegistration(Autofac.Core. IComponentRegistry componentRegistry, Autofac.Core.IComponentRegistration registration) {[/align]
[align=left] var needsCacheManager = registration.Activator.LimitType[/align]
[align=left] .GetConstructors()[/align]
[align=left] .Any(x => x.GetParameters()[/align]
[align=left] .Any(xx => xx.ParameterType == typeof(ICacheManager )));[/align]
[align=left] [/align]
[align=left] if (needsCacheManager) {[/align]
[align=left] registration.Preparing += (sender, e) => {[/align]
[align=left] var parameter = new TypedParameter([/align]
[align=left] typeof(ICacheManager ),[/align]
[align=left] e.Context.Resolve< ICacheManager>(new TypedParameter( typeof(Type ), registration.Activator.LimitType)));[/align]
[align=left] e.Parameters = e.Parameters.Concat( new[] { parameter });[/align]
[align=left] };[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
Cache Manager是与类型相关的,这实际上是CacheModule存在的意义所在。比如Orchard.Environment.DefaultOrchardHost和其他类型不会共享同一个DefaultCacheManager对象。
二、DefaultCacheManager:ICacheManager类
DefaultCacheManager类公开了两个方法:
[align=left] public ICache <TKey, TResult> GetCache<TKey, TResult>() {[/align]
[align=left] return _cacheHolder.GetCache<TKey, TResult>(_component);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public TResult Get<TKey, TResult>(TKey key, Func< AcquireContext<TKey>, TResult> acquire) {[/align]
[align=left] return GetCache<TKey, TResult>().Get(key, acquire);[/align]
[align=left] }[/align]
第 一个方法可以获取类型相关的ICache<TKey,TResult>(Cache<TKey,TResult>)对象集合;第 二个方法通过Key值获取具体的某一个Cache Result,即实际的缓存值。Cache<TKey,TResult>会在下面介绍。
不难看出,DefaultCacheManager是对ICacheHolder的简单封装,就算没有DefaultCacheManager类,也可以不怎么方便地使用缓存机制,因为实际的缓存存取是交给ICacheHolder来处理的,默认使用的是DefaultCacheHolder,这是一个应用程序域级的单例。
三、DefaultCacheHolder:ICacheHolder类
绝大多数的缓存机制都是采用字典的形式,DefaultCacheHolder中使用线程安全的ConcurrentDictionary<CacheKey, object>型字典来保存缓存,这里称为类型缓存字典,注意该字典中并不存储实际的缓存值。为了方便,在这里我们把CacheKey称为类型缓存字典Key;object称为类型缓存字典Value, 实际类型为泛型Cache<TKey,TResult>:ICache<TKey,TResult>的封闭类型。 Cache<TKey,Result>内部也有一个字典,类型为ConcurrentDictionary<TKey, CacheEntry>。在这里,TKey称为缓存字典Key,CacheEntry称为缓存字典Value。
CacheEntry有一个类型为TResult名为Result的属性,这里称为缓存Result,这才是实际的缓存值。
在分析源码的时候要特别区分这些我们约定的概念:
1、类型缓存字典、类型缓存字典Key、类型缓存字典Value
2、缓存字典、缓存字典Key、缓存字典Value和缓存Result。
在使用缓存时,我们是通过"缓存字典Key"来获取一个"缓存Result"。
DefaultCacheHolder仅公开了一个GetCache方法:
[align=left] public ICache<TKey, TResult> GetCache<TKey, TResult>(Type component) {[/align]
[align=left] var cacheKey = new CacheKey(component, typeof(TKey), typeof (TResult));[/align]
[align=left] var result = _caches.GetOrAdd(cacheKey, k => new Cache<TKey, TResult>(_cacheContextAccessor));[/align]
[align=left] return (Cache <TKey, TResult>)result;[/align]
[align=left] }[/align]
方法首先使用两个泛型参数的类型加上一个方法参数(Type型),可以构成一个CacheKey。CacheKey是一个三元组:
[align=left] class CacheKey : Tuple<Type, Type , Type> {[/align]
[align=left] public CacheKey(Type component, Type key, Type result)[/align]
[align=left] : base(component, key, result) {[/align]
[align=left] }[/align]
[align=left] }[/align]
然后从类型缓存字典中获取一个Cache<TKey, TResult>:ICache<TKey,TResult>对象。这时可以认为获取了一个类型相关的缓存字典。调用Cache<TKey, TResult>对象Get方法获取实际的缓存值。
DefaultCacheHolder 采用延迟缓存机制,在第一次从缓存中获取对象时才会去构建对象;提供可扩展的缓存到期、更新策略,比如使用Orchard.Services.Clock 类配合可以让缓存在某个具体的时间到期或一定时间间隔到期。缓存过期并不表示它在内存中被立即销毁,而是会在下一次尝试获取缓存的时候重新生成缓存。
相关类型(皆在Orchard.Caching命名空间下):
DefaultCacheManager : ICacheManager
DefaultCacheHolder : ICacheHolder
DefaultCacheContextAccessor : ICacheContextAccessor
DefaultParallelCacheContext : IParallelCacheContext
DefaultAsyncTokenProvider : IAsyncTokenProvider
AcquireContext<TKey>:IAcquireContext
SimpleAcquireContext : IAcquireContext
Signals : ISignals : IVolatileProvider : ISingletonDependency
Signals.Token : IVolatileToken(Private nested class)
Cache<TKey, TResult> : ICache<TKey, TResult>
CacheEntry(Private class)
Weak<T>
参考资料:
Autofac:Structuring With Modules
Autofac:Activation events
http://skywalkersoftwaredevelopment.net/orchard-development/api/autofac-module
相关文章推荐
- Android 轻量级轮播组件 CycleViewPager
- 使用Ubuntu的点滴记录-配置Tomcat
- dubbo超时 time out
- 集合第五发TreeSet和TreeMap
- Android菜鸟的成长笔记(28)——Google官方对Andoird 2.x提供的ActionBar支持
- baseAdapter
- 百度网盘普通会员和超级会员有什么区别?
- apply、call、bind区别、用法
- 二维数组 指针 形参 用一个关系图解决问题
- Android实现滑动功能的总结
- android虚拟机上安装SD卡
- ShaderForge学习1
- Unity中ScrollRect锁定元素详述(一)
- Orchard源码分析(6):Shell相关
- 【POJ】1084 Square Destroyer
- [linux basic]基础--信号
- 蓝桥杯一试题
- Eclipse常用快捷键总结
- struts2类型转换总结
- ggplot2-主题函数关系