惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
D
Docker
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Blog — PlanetScale
Blog — PlanetScale
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
博客园 - 【当耐特】
N
Netflix TechBlog - Medium
V
Visual Studio Blog
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
Recent Announcements
Recent Announcements
GbyAI
GbyAI
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
WordPress大学
WordPress大学
T
The Blog of Author Tim Ferriss
Engineering at Meta
Engineering at Meta
L
LangChain Blog
A
About on SuperTechFans
M
MIT News - Artificial intelligence
B
Blog

博客园 - alby

在 ASP.NET Core Web API 中处理 Patch 请求 一种有界队列(Bounded Buffer)的实现 基于 Mediasoup 的 Abp vNext 视频会议模块 使用 ASP.NET Core 作为 mediasoup 的信令服务器 ASP.NET Core 的 `Core` 有几种写法? ASP.NET Core MVC 授权的扩展:自定义 Authorize Attribute 和 IApplicationModelProvide OrchardCore 如何实现模块化( Modular )和 Multi-Tenancy [iOS]关于状态栏(UIStatusBar)的若干问题 [iOS]关于视频方向的若干问题 --2015-06-24-- Orchard源码分析(7.2):Controller相关 Orchard源码分析(7.1):Routing(路由)相关 Orchard源码分析(7):ASP.NET MVC相关 Orchard源码分析(6):Shell相关 Orchard源码分析(5.3):EndRequest事件处理(DefaultOrchardHost.EndRequest方法) Orchard源码分析(5.2):BeginRequest事件处理(DefaultOrchardHost.BeginRequest方法) Orchard源码分析(5.1):Host初始化(DefaultOrchardHost.Initialize方法) Orchard源码分析(5):Host相关(Orchard.Environment.DefaultOrchardHost类) Orchard源码分析(4.3):Orchard.Events.EventsModule类(Event Bus)
Orchard源码分析(4.4):Orchard.Caching.CacheModule类
alby · 2012-10-18 · via 博客园 - alby

概述

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>

参考资料: