Orchard 刨析:前奏曲
Orchard中大量使用了依赖注入,而实现依赖注入的组件就是Autofac,它在Orchard中扮演者非常重要的角色,多租户如是,模块如是,工作区也如是。今天就来讲讲Autofac在Orchard中的应用。
从OrchardStarter认识Autofac
OrchardStarter中向Ioc容器中注册了大量的服务,在此中的服务也是“root”域,根域。
Module注册
- builder.RegisterModule(new CacheModule());
这段话代表了注册一个Module,我们看看CacheModule内又是什么内容。


- CacheModule public class CacheModule : Module {
- protected override void Load(ContainerBuilder builder) {
- builder.RegisterType<DefaultCacheManager>()
- .As<ICacheManager>()
- .InstancePerDependency();
- }
- 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 });
- };
- }
- }
- }
Load方法:入口
AttachToComponentRegistration方法:事件通知
首先在Load方法内将DefaultCacheManager注册为ICacheManager并且是瞬态的。
在AttachToComponentRegistration方法中判断如果其他服务需要服务类型为ICacheManager的服务,则在该服务准备前将ICacheManager服务解析并赋给调用服务。
这边有意思的是Autofac默认支持构造函数注入,为什么还要写这么一段复杂的代码呢?我们来看一看DefaultCacheManager这个类。


- Code /// <summary>
- /// Constructs a new cache manager for a given component type and with a specific cache holder implementation.
- /// </summary>
- /// <param name="component">The component to which the cache applies (context).</param>
- /// <param name="cacheHolder">The cache holder that contains the entities cached.</param>
- public DefaultCacheManager(Type component, ICacheHolder cacheHolder) {
- _component = component;
- _cacheHolder = cacheHolder;
- }
可以看到DefaultCacheManager的构造函数有类型为Type的参数componet和类型为ICacheHolder参数的cacheHolder。
而cacheHolder在OrchardStarter中被注册
- builder.RegisterType<DefaultCacheHolder>().As<ICacheHolder>().SingleInstance();
而component的参数没有找到在哪被注册。
聪明的人可能已经猜到了AttachToComponentRegistration方法内的内容就是为了传入这个类型为Type名称叫component的参数。。可真不容易啊。
这个方法中他把需要使用到ICacheManager服务的类型当作component传给了DefaultCacheManager,至于为什么我们后面在做分析。
类型注册
简单的类型注册
- builder.RegisterType<DefaultHostEnvironment>().As<IHostEnvironment>().SingleInstance();
- 同时注册多个服务
- builder.RegisterTypes(new[] { typeof(WalmartShop), typeof(CarrefourShop) }).As<IShop>();
生命周期
在Autofac中常用的4种生命周期分别是:瞬态、单例、当前域单例、指定域下单例、某一个对象下的共享域。
其实说白了就只有2种:瞬态和单例,因为Autofac支持子域(子容器)所以才衍生出很多种的生命周期,除上之外官方还提供了在当前请求单例等扩展。
瞬态
每一次解析服务时服务实例都是一个新的实例。
单例
每一次解析服务时如果服务以及被创建则直接返回否则创建一个实例并返回。
域
Autofac中的域非常的惊艳。默认的域Tag为”root”。
在Autofac中有一个概念跟面向对象很像,子域可以拥有根域的服务而根域不可以拥有子域的服务,是不是跟oop中的子类跟父类很像。
一个小小的Demo
参数注入
这边其实是对服务的构造函数进行注入。
一个简单的Demo
服务类
入口
服务Key
如果我们同时将WalmartShop和CarrefourShop注册为IShop我们要怎么区分调用的服务呢?别担心Autofac考虑到了。
一个简单的Demo
Named其实就是Keyed的重载,反编译代码就可以看到两者唯一的区别就是Named方法限制了参数必须为string类型而Keyed方法则不限制参数类型为object。
隐式关系类型
Lazy
Owned
Func
IEnumerable、IList 、ICollection
Meta
IIndex
一个简单的Demo
服务类
入口
写在最后
这边讲了OrchardStarter中常用的注册方式,对后面的内容有很大的作用,后面还会涉及Autofac中更多的东西,会根据章节进行讲解。
为了本系列的读者有更好的交流环境提供QQ群一个:299744835
Orchard 刨析:前奏曲的更多相关文章
- Orchard 刨析:Logging
最近事情比较多,有预研的,有目前正在研发的,都是很需要时间的工作,所以导致这周只写了两篇Orchard系列的文章,这边不能保证后期会很频繁的更新该系列,但我会写完这整个系列,包括后面会把正在研发的东西 ...
- Orchard 刨析:Caching
关于Orchard中的Caching组件已经有一些文章做了介绍,为了系列的完整性会再次对Caching组件进行一次介绍. 缓存的使用 在Orchard看到如下一段代码: 可以看到使用缓存的方法Get而 ...
- Orchard 刨析:导航篇
之前承诺过针对Orchard Framework写一个系列.本应该在昨天写下这篇导航篇,不过昨天比较累偷懒的去玩了两盘单机游戏哈哈.下面进入正题. 写在前面 面向读者 之前和本文一再以Orchard ...
- Apollo 刨析:Localization
九月 30 2014 11:27 上午 admin 0 Comments 今天我们来看一看Apollo中的Localization Component. 本地化在Apollo中的使用 像这样的 ...
- Learning Cocos2d-x for WP8(2)——深入刨析Hello World
原文:Learning Cocos2d-x for WP8(2)--深入刨析Hello World cocos2d-x框架 在兄弟篇Learning Cocos2d-x for XNA(1)——小窥c ...
- MapReduce源码刨析
MapReduce编程刨析: Map map函数是对一些独立元素组成的概念列表(如单词计数中每行数据形成的列表)的每一个元素进行指定的操作(如把每行数据拆分成不同单词,并把每个单词计数为1),用户可以 ...
- 30s源码刨析系列之函数篇
前言 由浅入深.逐个击破 30SecondsOfCode 中函数系列所有源码片段,带你领略源码之美. 本系列是对名库 30SecondsOfCode 的深入刨析. 本篇是其中的函数篇,可以在极短的时间 ...
- Golang 性能测试 (3) 跟踪刨析 golang trace
简介 对于绝大部分服务,跟踪刨析是用不到的.但是如果遇到了下面问题,可以不妨一试: 怀疑哪个协程慢了 系统调用有问题 协程调度问题 (chan 交互.互斥锁.信号量等) 怀疑是 gc (Garbage ...
- 温故知新-多线程-深入刨析volatile关键词
文章目录 摘要 volatile的作用 volatile如何解决线程可见? CPU Cache CPU Cache & 主内存 缓存一致性协议 volatile如何解决指令重排序? volat ...
随机推荐
- Tomcat常用的优化技巧
(1)屏蔽DNS查询 Web应用程序可以通过Web容器提供的getRemoteHost()方法获得访问Web应用客户的IP地址和名称,但是这样会消耗Web容器的资源,并且还需要通过IP地址和DNS服务 ...
- 烂泥: KVM虚拟机Linux系统增加硬盘
本文由秀依林枫提供友情赞助,首发于烂泥行天下. Linux虚拟机在使用过程中,硬盘空间不够使用.由于前期没有做LVM,所以只能手动添加新的硬盘. 给虚拟机添加硬盘有两种方法: 1.通过virsh at ...
- 修改镜像文件EI.CFG
一.EI.cfg说明 Windows 7 安装光盘中存在着 SOURCES\EI.CFG 这样一个配置文件.EI.cfg 是特定于 Windows 安装程序的配置文件,用于确定在安装过程中应该使用哪种 ...
- Maximum Subsequence Sum(接上篇)
Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, ...
- Hadoop could not find or load main class
Error: Could not find or load main class <class_name> 我在尝试使用hadoop definitive guide的代码做练习时,遇到一 ...
- BI测试工具之跨数据库数据对比,支持oracle,sqlserver
应用场景: 本周在进行SIT,我帮助仅有的一个测试妹妹对部分表进行数据质量验证,第一步需要做的就是比对source与stage表的table definition 与 数据内容的一致性. 本项目使用的 ...
- excel vba 当cell的值变化时 进行判断操作
示例效果: ----------- 在excel的sheet1中, 当A列的值 大于100时 ,其对应B列背景显示红色,C列显示"有数据" 否则,B列背景色正常,C列清空相应的数据 ...
- 使用DateLocaleConverter和SimpleDateFormat实现字符串转换成日期
使用DateLocaleConverter: public static void change() { String birthday = "1990-12-32"; DateL ...
- ok,今天讲讲linux的部分指令吧
Linux布置服务 cd 进入 ../ 上一层目录 sh shutdown.sh -------tomcat的关闭指令 sh startup.sh ------ ...
- 怎么运用好ZBrush中Magnify膨胀笔刷
Magnify膨胀笔刷是ZBrush笔刷中经常使用的,利用该笔刷可绘制中心向四周膨胀的效果.本文内容向大家介绍ZBrush®中膨胀笔刷以便大家熟悉它的用法和特性. 查看更多内容请直接前往:http:/ ...