一、Autofac入门
想要将autofac集成到你的应用程序中需要经过如下步骤:
1、使用控制翻转(IoC)的思想架构你的应用程序;
2、添加autofac引用;
3、在应用程序入口...(At application startup...);
4、创建一个ContainerBuilder对象;
5、注册组件;
6、为以后的使用,生成并保存容器;
7、在应用执行期间...(During application execution...);
8、从容器中创建一个生命周期域;
9、使用生命周期域解析(resolve)组件实例。
这个入门指导将带领你通过一个简单的控制台应用程序来完成以上这些步骤。一旦你掌握了这些基础知识,就可以进一步学习更高级的概念以及如何将autofac集成到WCF、ASP.NET或其他类型的应用程序中。
1.1、构建应用(Structuring the Application)
控制反转背后的思想是,与其将应用中的类捆绑到一起从而提升相互间的依赖关系,不如在类被构造时再通过注入的方式引入相关的依赖。如果你想更深入了解控制反转,马丁福勒有一篇优秀的文章解释了依赖注入/控制反转。
在我们的控制台应用程序示例中,我将定义一个输出当前日期的类。但是我们并不想将他直接与控制台绑定,因为我们可能希望在今后能够对这个类进行测试或者将该类应用到控制台意外的地方。
我会尽可能的对输出日期的方式进行抽象,以便于今后我们能够使用其他的版本替换他。
我将会这样设计我们的类:
namespace DemoApp
{
//接口帮助我们将“输出"从控制台类解耦,
//我们并不关心输出操作是如何执行的,只要能输出就够了。
public interface IOutput
{
void Write(string content);
} //ConsoleOuput实现了IOutput接口,
//他将信息写到了控制台。从技术上来说我们还可以通过
//实现IOutput接口,将信息写入跟踪调试或者其他地方
public class ConsoleOutput : IOutput
{
public void Write(string content)
{
Console.WriteLine(content);
}
} //这个接口解耦了输入日期的机制,与IOutput一样,实际的处理机制
//通过接口进行了抽象
public interface IDateWriter
{
void WriteDate();
} //注意TodayWriter定义了一个使用IOutput作为形参的构造函数,
//这样做可以根据传入的具体具体类型将日期写到任何地方,他实现了
//WriteDate()方法来输入日期,你可以让他以不同的格式输出到
//不同的地方
public class TodayWriter : IDateWriter
{
private IOutput _output;
public TodayWriter(IOutput output)
{
this._output = output;
}
public void WriteDate()
{
this._output.Write(DateTime.Today.ToShortDateString());
}
}
}
现在我们有一个合理的结构来设置依赖关系,那就让我们通过autofac来将他们结合到一起吧!
1.2、添加autofac引用
第一步是将autofac添加到你的应用。在这个应用中我们只是用core autofac(这里翻译成核心autofac感觉怪怪的,直接上英文还显得明了一些),其他的应用类型可以使用额外的Autofac integration libraries。
最简单的方式是通过NuGet来添加autofac引用,”Autofac"包已经包含了你需要的所有核心功能。

1.3、应用程序入口
在应用程序入口你需要创建一个ContainerBuilder,并将组件注册到其中。组件可能是一个表达式、.net类型或者其他的暴露了一个或多个服务并能够被其他依赖项所使用的代码。简单来说,可以将组件理解为实现了某个接口的.net类型,列如:
public class SomeType : IService
{
}
你可以通过两种方式来识别它:一种方式可以将其看作本身的类型(SomeType),另一种可以将其视为接口(IService)。在这种情况下组件就是SomeType,而其所暴露的服务就是SomeType和IService。
在autofac中,你需要将其注册到ContainerBuilder中,比如:
//创建ContainerBuilder对象
var builder = new ContainerBuilder(); //通常情况下你所感兴趣的是组件通过接口暴露的服务
builder.RegisterType<SomeType>().As<IService>(); //然而如果你同时也对组件通过自身类型暴露的服务感兴趣(并不常见),可以如下方式进行注册:
builder.RegisterType<SomeType>().AsSelf().As<IService>();
在我们的应用中,需要对我们所有的组件(class)进行注册,并暴露他们所提供的服务(Interface)。
我们同样需要保存我们容器,以便于之后通过容器来解析类型。
using System;
using Autofac; namespace DemoApp
{
public class Program
{
private static IContainer Container{ get; set; }
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<ConsoleOutput>().As<IOutput>();
builder.RegisterType<TodayWrite>().As<IDateWrite>();
Container = builder.Build(); //我们将在WriteDate方法中使用依赖注入,该方法我们稍后实现。
WriteDate();
}
}
}
现在,我们已经拥有了容器,注册了组件并暴露了适当的服务,现在就让我们来使用它。
1.4、应用的执行
在应用执行时,你需要使用注册的组件。为此,将从一个生命周期域中解析组件。
容器本身是一个生命周期域,技术上来说,你可以直接通过容器进行解析。然后这样的做法是不被推荐的。
当你解析一个组件,根据你定义的实例范围,一个新的对象实例将被创建。(解析一个组件大致等效于“new”一个类的实例,这是最最简化的一种说法,但从比喻的角度来看却是很恰当的。)一些组件可能需要被销毁(比如实现了IDisposable接口的组件),当生命周期域被释放的时候autofac能够帮你处理这些组件。
然而,container存在于你的应用程序生命周期中,如果你直接从容器中解析了很多的组件,最终将会有很多的组件实例等待销毁。这很糟糕(这可能会导致内存溢出)。
相反,从container中创建子生命周期域,并从子生命周期域中解析组件,那么当子生命周期域结束时所有从该域中创建的组件都将被销毁。(当你使用Autofac integration libraries时,创建子生命周期域的任务将由autofac完成,你不必过多考虑)
在我们的例子中,我将实现WriteDate方法,在一个域中执行输出,并在完成后销毁该域。
namespace DemoApp
{
public class Program
{
private IContainer Container{ get; set; } static void Main(string[] args)
{
// ...the stuff you saw earlier...
} public static void WriteDate()
{
//创建域,解析IDateWriter
using(var scope = Container.BeginLifetimeScope())
{
var writer = scope.Resolve<IDateWriter>();
writer.WriterDate();
}
}
}
}
现在当你运行程序时:
1、“WriteDate”方法向autofac请求一个IDateWtiter;
2、autofac发现IDateWtiter映射到TodayWriter,然后创建TodayWriter对象;
3、autofac发现TodayWriter的构造函数需要一个IOutput参数;
4、autofac发现IOutput映射到ConsoleOutput,然后创建ConsoleOutput实例;
5、autofac使用ConsoleOutput实例完成TodayWriter的创建工作;
6、autofac完成TodayWriter创建,并将TodayWriter实例返回给“WriteDate”。
以后,如果你希望你的应用程序输出不同的日期,你可以实现不同的IDateWriter并修改应用程序入口处的注册,这样你就不必在修改其他的类。耶,控制反转!!
注意:一般来说,服务定位很大程度上被视为一种“反模式”,也就是说到处都通过手动创建域(scope)以及直接使用container并不是最好的选择。使用Autofac integration libraries通常不需要我们去手动的完成示例应用程序中创建域以及解析组件的工作,在应用程序中“顶层”定位以及手动解析组件是非常罕见的,当然,如何设计你的应用程序取决于你自己。
PS:本系列博客是对autofac英文资料的翻译,主要目的是为了提高自己英文阅读能力,同时能够帮助有需要的人,原文地址http://autofac.readthedocs.org/en/latest/getting-started/index.html。翻译过程中我将“resolve”译为“解析”,但在阅读中感觉意思并未通达,绞尽脑汁仍未找到恰当的词语代替,若各位园友有合适翻译还望指教。
一、Autofac入门的更多相关文章
- Autofac 入门
Autofac 入门文档 原文链接:http://docs.autofac.org/en/latest/getting-started/index.html 在程序中使用Autofac的基本模式是: ...
- Autofac入门
注意:本文为原创文章,任何形式的转载.引用(包括但不限于以上形式)等,须先征得作者同意,否则一切后果自负. 简介 Autofac 是一个令人着迷的.NET IoC 容器. 它管理类之间的依赖关系.当应 ...
- [翻译] Autofac 入门文档
原文链接:http://docs.autofac.org/en/latest/getting-started/index.html 在程序中使用Autofac的基本模式是: 用控制反转(IoC)的思想 ...
- .NET手记-Autofac入门Getting Started
内容主要翻译自官方文档,原文请看:http://autofac.readthedocs.org/en/latest/getting-started/index.html#application-sta ...
- [转]ASP.NET MVC IOC 之AutoFac攻略
本文转自:http://www.cnblogs.com/WeiGe/p/3871451.html 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用A ...
- ASP.NET MVC IOC 之AutoFac攻略
一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌似更为普遍,于是捯饬了两天,发现这个东东确实是个高大上的IOC容器~ Autofa ...
- 不复杂的Autofac注入
private static void SetAutofacWebAPI() { var builder = new ContainerBuilder(); #region 配置注册方法 string ...
- Autofac 一个使用Demo
一:接口 二:实现: 三:调用: 首先上图: 一:接口代码 public interface IPersonDa { PersonEntity Get(int id); } 二:实现 public c ...
- ASP.NET MVC IOC 之AutoFac
ASP.NET MVC IOC 之AutoFac攻略 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌似更为普遍,于是捯饬了两天, ...
随机推荐
- iOS import导入pod第三方库不提示问题
pod 导入第三方库后,使用import 不提示第三方库头文件. 解决办法: 选择target -> BuildSettings -> search Paths 下的 User Heade ...
- 洛谷 P3392 涂国旗
P3392 涂国旗 题目描述 某国法律规定,只要一个由N*M个小方块组成的旗帜符合如下规则,就是合法的国旗.(毛熊:阿嚏——) 从最上方若干行(>=1)的格子全部是白色的. 接下来若干行(> ...
- javascript的DOM操作(二)
<html> <title>学习DOM</title> <a id="wen">文本</a> <input nam ...
- CSS定义网页滚动条
(一)滚动条样式主要涉及到如下CSS属性: overflow属性: 检索或设置当对象的内容超过其指定高度及宽度时如何显示内容overflow: auto; 在需要时内容会自动添加滚动条overflow ...
- GSoap的使用(调用webservice接口)
由于本人写项目时使用到C++要调用C#写得后台服务器发布的webservice,因此抽出来了一点时间整理相关的知识如下 gSOAP是一个绑定SOAP/XML到C/C++语言的工具,使用它可以简单快速地 ...
- UVA 10791 Minimum Sum LCM
唯一分解定理 把n分解为 n=a1^p1*a2^p2*...的形式,易得每个ai^pi作为一个单独的整数最优. 坑: n==1 ans=2: n因子种数只有一个 ans++: 注意溢出 ...
- Java学习笔记--Swing
1.创建框架 AWT中Frame类用来描述顶层窗口,在Swing中,这个类的名为JFrame,它从Frame类扩展. JFrame是少数几个在Swing不用绘制在画布上的组件之一,因此,它的修饰部件( ...
- Mysql 插入记录时检查记录是否已经存在,存在则更新,不存在则插入记录SQL
我们在开发数据库相关的逻辑过程中, 经常检查表中是否已经存在这样的一条记录, 如果存在则更新或者不做操作, 如果没有存在记录,则需要插入一条新的记录. 这样的逻辑固然可以通过两条sql语句完成. SE ...
- PowerShell_零基础自学课程_8_高级主题:WMI对象和COM组件
本系列文章从最初的初识开始,基本上可以完成一些简单的系统管理了,为了更方便的管理系统,同时为了更好的发掘系统的性能,就需要用到系统提供 的一些高级特性,在Windows Server系列的OS中,如果 ...
- ElasticSearch大批量数据入库
最近着手处理大批量数据的任务. 现状是这样的,一个数据采集程序承载大批量数据的存储和检索.后期可能需要对大批量数据进行统计. 数据分布情况 13个点定时生成采集结果到4个文件(小文件生成周期是5分钟) ...