概述
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>
 
参考资料:

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

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

    概述 Host 是应用程序域级的单例,代表了Orchard应用程序.其处理应用程序生命周期中的初始化.BeginRequest事件.EndRequest事件等. 可以简单理解为HttpApplicat ...

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

    上一篇分析了BeanFactory体系的2个类,SimpleAliasRegistry和DefaultSingletonBeanRegistry——Spring源码分析——BeanFactory体系之 ...

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

      本文主要参考官方文档"How Orchard works"以及Orchardch上的翻译.   源码分析应该做到庖丁解牛,而不是以管窥豹或瞎子摸象.所以先对Orchard架构有 ...

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

    上一篇介绍了BeanFactory体系的所有接口——Spring源码分析——BeanFactory体系之接口详细分析,本篇就接着介绍BeanFactory体系的抽象类和接口. 一.BeanFactor ...

  5. Thinkphp源码分析系列(二)–引导类

    在上一章我们说到,ThinkPHP.php在设置完框架所需要的变量和调教好环境后,在最后调用了  Think\Think::start();  即Think命名空间中的Think类的静态方法start ...

  6. spring源码分析系列 (5) spring BeanFactoryPostProcessor拓展类PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer解析

    更多文章点击--spring源码分析系列 主要分析内容: 1.拓展类简述: 拓展类使用demo和自定义替换符号 2.继承图UML解析和源码分析 (源码基于spring 5.1.3.RELEASE分析) ...

  7. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第1节: FastThreadLocal的使用和创建

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 概述: FastThreadLocal我们在剖析堆外内存分配的时候简单介绍过, 它类似于JDK的ThreadL ...

  8. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第2节: FastThreadLocal的set方法

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第二节: FastThreadLocal的set方法 上一小节我们学习了FastThreadLocal的创建和 ...

  9. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第3节: recycler的使用和创建

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第三节: recycler的使用和创建   这一小节开始学习recycler相关的知识, recycler是n ...

  10. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第4节: recycler中获取对象

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第四节: recycler中获取对象 这一小节剖析如何从对象回收站中获取对象: 我们回顾上一小节demo的ma ...

随机推荐

  1. form 表单用php来跳转页面

    action="submit.php" method="post"  fomr 表单的提交跳转:method =post/get,get密码和用户的可见性,密码 ...

  2. Oracle计算时间差表达式

    有两个日期数据START_DATE,END_DATE,欲得到这两个日期的时间差(以天,小时,分钟,秒,毫秒): 天: ROUND(TO_NUMBER(END_DATE - START_DATE)) 小 ...

  3. 【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)

    3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 821  Solved: 502[Submit][Status ...

  4. Java包的命名规范

    indi : 个体项目,指个人发起,但非自己独自完成的项目,可公开或私有项目,版权主要属于发起者. 包名为indi.发起者名.项目名.模块名*.*.* pers : 个人项目,指个人发起,独自完成,可 ...

  5. Genymotion关于【启动后player.exe已停止运行】解决方案总结

    1. 你硬盘空间不足,或是暂存区不够,请少执行一些程序或关掉一些p2p的程序,或是到控制面板卸载一些不必要的程序.最好的建议是定期进行硬盘清理,确保不浪费多余空间 ---以上来源(http://www ...

  6. ecshop /flow.php SQL Injection Vul

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 ECSHOP的配送地址页面网页没有验证地区参数的有效性,存在sql注入漏 ...

  7. c#自适应窗体的实现

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  8. MVC5-3 Result分析

    众多的Result 使用MVC进行开发,可以看到有ActionResult.ContentReuslt.JsonResult..等,今天对这些Result进行背后分析.它到底是如何做到的 Action ...

  9. MVC5-1 ASP.NET的管道流

    MVC5 和WebForm的区别 WebForm是一个Page贯穿了一个.CS代码. 1对1 = 耦合在一起 MVC在Controller中将 bihind和page进行了分离. 多对多 = 松耦合 ...

  10. 基本概率分布Basic Concept of Probability Distributions 5: Hypergemometric Distribution

    PDF version PMF Suppose that a sample of size $n$ is to be chosen randomly (without replacement) fro ...