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

cacheHolderOrchardStarter中被注册

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 刨析:前奏曲的更多相关文章

  1. Orchard 刨析:Logging

    最近事情比较多,有预研的,有目前正在研发的,都是很需要时间的工作,所以导致这周只写了两篇Orchard系列的文章,这边不能保证后期会很频繁的更新该系列,但我会写完这整个系列,包括后面会把正在研发的东西 ...

  2. Orchard 刨析:Caching

    关于Orchard中的Caching组件已经有一些文章做了介绍,为了系列的完整性会再次对Caching组件进行一次介绍. 缓存的使用 在Orchard看到如下一段代码: 可以看到使用缓存的方法Get而 ...

  3. Orchard 刨析:导航篇

    之前承诺过针对Orchard Framework写一个系列.本应该在昨天写下这篇导航篇,不过昨天比较累偷懒的去玩了两盘单机游戏哈哈.下面进入正题. 写在前面 面向读者 之前和本文一再以Orchard ...

  4. Apollo 刨析:Localization

    九月 30 2014 11:27 上午     admin 0 Comments 今天我们来看一看Apollo中的Localization Component. 本地化在Apollo中的使用 像这样的 ...

  5. 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 ...

  6. MapReduce源码刨析

    MapReduce编程刨析: Map map函数是对一些独立元素组成的概念列表(如单词计数中每行数据形成的列表)的每一个元素进行指定的操作(如把每行数据拆分成不同单词,并把每个单词计数为1),用户可以 ...

  7. 30s源码刨析系列之函数篇

    前言 由浅入深.逐个击破 30SecondsOfCode 中函数系列所有源码片段,带你领略源码之美. 本系列是对名库 30SecondsOfCode 的深入刨析. 本篇是其中的函数篇,可以在极短的时间 ...

  8. Golang 性能测试 (3) 跟踪刨析 golang trace

    简介 对于绝大部分服务,跟踪刨析是用不到的.但是如果遇到了下面问题,可以不妨一试: 怀疑哪个协程慢了 系统调用有问题 协程调度问题 (chan 交互.互斥锁.信号量等) 怀疑是 gc (Garbage ...

  9. 温故知新-多线程-深入刨析volatile关键词

    文章目录 摘要 volatile的作用 volatile如何解决线程可见? CPU Cache CPU Cache & 主内存 缓存一致性协议 volatile如何解决指令重排序? volat ...

随机推荐

  1. 集算器协助java处理多样性数据源之MongoDB

    MongoDB不支持join,其官网上推荐的unity jdbc可以把数据取出来进行二次计算实现join运算,但这些join.group.函数.表达式等高级功能都是收费版才有,而且即使是收费版本,对子 ...

  2. 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单

    我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...

  3. Mac OS X 快捷键

    启动快捷键 按下按键或组合键,直到所需的功能出现(例如,在启动过程中按住 Option 直到出现“启动管理程序”,或按住 Shift 直到出现“安全启动”).提示:如果启动功能未起作用,而您使用的是第 ...

  4. TCP/IP详解--TCP首部选项中时间戳选项

    一.简介 TCP时间戳选项会在TCP包头增加12个字节,以一种比重发超时更精确的方法来启用对RTT 的计算.   二.作用 ) TCP时间戳位于TCP选项中,kind=:lenth=:data由tim ...

  5. Java中的静态方法和单例模式比较

    区别 单例模式方法 静态方法 实例 创建实例 无 运行 类的实例的方法 类的方法 也可以通过实例化,在通过类的实例来运行 是否可以被重写 可以 可以(子类的该方法也必须是静态方法) 调用其他静态方法 ...

  6. makefile自动生成目标与依赖的关系

    有main.c: #include <stdio.h> #include "command.h" int main(int argc, const char *argv ...

  7. 事件查看器常见ID代码解释

    ID 类型 来   源 代 表 的 意 义 举 例 解 释 信息 Serial 在验证 \Device\Serial1 是否确实是串行口时,系统检测到先进先出方式(fifo).将使用该方式. 错误 W ...

  8. ZOJ 1808 Immediately Decodable

    字典树较简单题,无需维护标记,注意细节即可. 代码: #include <iostream> #include <cstdio> #include <cstring> ...

  9. Android学习----自适应国际化语言

    [前言] 自适应的知识与编程无关,关键在于配置文件的修改.自适应的内容包括:语言.屏幕.平台.今天就来说一下如何自适应国际化言. internationalization (国际化)简称:i18n,因 ...

  10. 第17章 内存映射文件(3)_稀疏文件(Sparse File)

    17.8 稀疏调拨的内存映射文件 17.8.1 稀疏文件简介 (1)稀疏文件(Sparse File):指的是文件中出现大量的0数据,这些数据对我们用处不大,但是却一样的占用空间.NTFS文件系统对此 ...