Orchard源码分析(4.4):Orchard.Caching.CacheModule类

概述

CacheModule也是一个Autofac模块。

一、CacheModule类

CacheModule将DefaultCacheManager注册为ICacheManager:

public class CacheModule : Module {

protected override void Load( ContainerBuilder builder) {

builder.RegisterType<DefaultCacheManager>()

.As< ICacheManager>()

.InstancePerDependency();

}

//...

}

如果类有一个接受ICacheManager型的参数的构造函数,Autofac容器在解析(Resolve)该类生成对象之前,会先解析一个ICacheManager型对象作为参数:

public class CacheModule : Module {

//...

protected override void AttachToComponentRegistration(Autofac.Core. IComponentRegistry componentRegistry, Autofac.Core.IComponentRegistration registration) {

var needsCacheManager = registration.Activator.LimitType

.GetConstructors()

.Any(x => x.GetParameters()

.Any(xx => xx.ParameterType == typeof(ICacheManager )));

if (needsCacheManager) {

registration.Preparing += (sender, e) => {

                    var parameter = new TypedParameter(

                        typeof(ICacheManager ),

                        e.Context.Resolve< ICacheManager>(new TypedParameter( typeof(Type ), registration.Activator.LimitType)));

                    e.Parameters = e.Parameters.Concat( new[] { parameter });

};

}

}

}

Cache Manager是与类型相关的,这实际上是CacheModule存在的意义所在。比如Orchard.Environment.DefaultOrchardHost和其他类型不会共享同一个DefaultCacheManager对象。

二、DefaultCacheManager:ICacheManager类

DefaultCacheManager类公开了两个方法:

public ICache <TKey, TResult> GetCache<TKey, TResult>() {

return _cacheHolder.GetCache<TKey, TResult>(_component);

}

public TResult Get<TKey, TResult>(TKey key, Func< AcquireContext<TKey>, TResult> acquire) {

return GetCache<TKey, TResult>().Get(key, acquire);

}

第 一个方法可以获取类型相关的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方法:

public ICache<TKey, TResult> GetCache<TKey, TResult>(Type component) {

var cacheKey = new CacheKey(component, typeof(TKey), typeof (TResult));

var result = _caches.GetOrAdd(cacheKey, k => new Cache<TKey, TResult>(_cacheContextAccessor));

return (Cache <TKey, TResult>)result;

}

方法首先使用两个泛型参数的类型加上一个方法参数(Type型),可以构成一个CacheKey。CacheKey是一个三元组:

class CacheKey : Tuple<Type, Type , Type> {

public CacheKey(Type component, Type key, Type result)

: base(component, key, result) {

}

}

然后从类型缓存字典中获取一个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

时间: 2024-11-05 13:34:27

Orchard源码分析(4.4):Orchard.Caching.CacheModule类的相关文章

Orchard源码分析(5):Host相关(Orchard.Environment.DefaultOrchardHost类)

概述 Host 是应用程序域级的单例,代表了Orchard应用程序.其处理应用程序生命周期中的初始化.BeginRequest事件.EndRequest事件等. 可以简单理解为HttpApplication的功能转移到了Host身上.从源码角度上看,Host对应的是实现了IOrchardHost接口的 DefaultOrchardHost类. 回顾一下之前对Orchard.Web.MvcApplication类的分析.在Orchard启动时,会创建一个DefaultOrchardHost对象:

Spring源码分析——BeanFactory体系之抽象类、类分析(二)

上一篇分析了BeanFactory体系的2个类,SimpleAliasRegistry和DefaultSingletonBeanRegistry——Spring源码分析——BeanFactory体系之抽象类.类分析(一),今天继续分析. 一.工厂Bean注册支持——FactoryBeanRegistrySupport 废话不多说,直接看我注释的源码: /* * Copyright 2002-2012 the original author or authors. * * Licensed und

Cordova Android源码分析系列二(CordovaWebView相关类分析)

本篇文章是Cordova Android源码分析系列文章的第二篇,主要分析CordovaWebView和CordovaWebViewClient类,通过分析代码可以知道Web网页加载的过程,错误出来,多线程处理等. CordovaWebView类分析 CordovaWebView类继承了Android WebView类,这是一个很自然的实现,共1000多行代码.包含了PluginManager pluginManager,BroadcastReceiver receiver,CordovaInt

Orchard源码分析(1):Orchard架构

本文主要参考官方文档"How Orchard works"以及Orchardch上的翻译. 源码分析应该做到庖丁解牛,而不是以管窥豹或瞎子摸象.所以先对Orchard架构有个整体的了解,以及对一些基本概念有所认识. 创建一个基于Web的CMS(内容管理系统)不同于创建一个普通的Web应用程序:它更像是建立一个应用程序容器. 这样一个系统,必须拥有优良的开放性.可扩展性.但是作为一个可扩展系统,它可能会面临应用程序"可用性"的挑战:在系统中的核心模块与未知的未来模块的

Orchard源码分析(1):Orchard架构 (转)

源码分析应该做到庖丁解牛,而不是以管窥豹或瞎子摸象.所以先对Orchard架构有个整体的了解,以及对一些基本概念有所认识. 创建一个基于Web的CMS(内容管理系统)不同于创建一个普通的Web应用程序:它更像是建立一个应用程序容器. 这样一个系统,必须拥有优秀的开放性.可扩展性.但是作为一个可扩展系统,它可能会面临应用程序"可用性"的挑战:在系统中的核心模块与未知的未来模块的组合,包括用户界面级别的整合.编排所有这些小零件,让互不知道的彼此的模块成一个连贯的整体,是Orchard是关键

Spring源码分析——BeanFactory体系之抽象类、类分析(一)

上一篇介绍了BeanFactory体系的所有接口——Spring源码分析——BeanFactory体系之接口详细分析,本篇就接着介绍BeanFactory体系的抽象类和接口. 一.BeanFactory的基本类体系结构(类为主): 上图可与 Spring源码分析——BeanFactory体系之接口详细分析 的图结合分析,一个以接口为主,一个以类为主(PS:Spring的体系结构要分析清楚,不得不曲线救国啊!不然27寸屏幕给我画估计都装不下.). 具体: 1.7层的类体系继承. 2.Abstrac

Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)----&gt;第5节: 同线程回收对象

Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第五节: 同线程回收对象 上一小节剖析了从recycler中获取一个对象, 这一小节分析在创建和回收是同线程的前提下, recycler是如何进行回收的 回顾第三小节的demo中的main方法: public static void main(String[] args){ User user1 = RECYCLER.get(); user1.recycle(); User user2 = RECYCLER

Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)----&gt;第6节: 异线程回收对象

Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第六节: 异线程回收对象 异线程回收对象, 就是创建对象和回收对象不在同一条线程的情况下, 对象回收的逻辑 我们之前小节简单介绍过, 异线程回收对象, 是不会放在当前线程的stack中的, 而是放在一个WeakOrderQueue的数据结构中, 回顾我们之前的一个图: 8-6-1 相关的逻辑, 我们跟到源码中: 首先从回收对象的入口方法开始, DefualtHandle的recycle方法: public

jQuery 源码分析(十四) 数据操作模块 类样式操作 详解

jQuery的属性操作模块总共有4个部分,本篇说一下第3个部分:类样式操作部分,用于修改DOM元素的class特性的,对于类样式操作来说,jQuery并没有定义静态方法,而只定义了实例方法,如下: addClass(value) ;为匹配元素集合中的每个元素添加一个或多个类样式,通过修改DOM属性className来修改类样式,value可以是个以空格分隔的类样式或者一个函数(返回一个或多个以空格分隔的类样式) hasClass(selector)   ;检测匹配元素中的任意元素是否含有指定的类