您的位置:首页 > 其它

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: