【写在前面】尝试做完一件工作之外自我觉得有意义的一件事,那就从翻译Autofac的帮助文档吧。

入门指南

将Autofac集成你的应用程序的步骤通常很简单,一般是:

  • 时刻以IOC(控制反转)的思想来规划你的应用程序
  • 在你的Porject中添加Autofac引用
  • 按照如下步骤设计应用程序的启动环节
    • 创建一个ContainerBuilder
    • 向ContainerBuilder注册组件
    • 通过ContainerBuilder的Build()方法获得Container(后续需用到)
  • 在应用程序运行环节时,按如下步骤执行
    • 通过Container获得一个lifetime scope
    • 通过lifetime scope解析出组件实例
    • 通过实例继续执行

本篇将通过入门指南实现一个简单的Console应用程序,一旦有了基础,后续可以延伸集成WCF、ASP.NET等等。

规划应用程序

先简单解释一下IOC(控制反转)。
通常情况下,类A若需要类B的一些功能,则在类A中需要通过“new”操作来完成创建和使用功能,这样在代码层面就固定住了类A和类B之间的相互依赖关系。这样的“依赖”,在后续的重构或修改时,影响面很大。
而IOC(控制反转)的思维,则是取消,由类A来创建类B,变更为在执行期间,由IOC容器来根据需要和约定自动创建类B来给类A使用。

Martin Fowler有一篇著名的文章,解释何谓IOC,可以点击“链接”查看。

在本篇的示例中,我们将定义一个类,这个类可以输出一些数据;但我们不想和Console绑定住,因为我们并不能确定在实际使用过程中Console是否真的可用。

我们通常可以这样实现:

using System;

namespace DemoApp
{
// 定义个输出接口
public interface IOutput
{
void Write(string content);
} // 为接口实现Console方式的输出
public class ConsoleOutput : IOutput
{
public void Write(string content)
{
Console.WriteLine(content);
}
} // 定义一个书写器接口
public interface IDateWriter
{
void WriteDate();
} // 实现书写器接口,输出当前日期,请注意,它依赖于IOutput接口
// 在运行时,才能获得具体的输出形式
public class TodayWriter : IDateWriter
{
private IOutput _output;
public TodayWriter(IOutput output)
{
this._output = output;
} public void WriteDate()
{
this._output.Write(DateTime.Today.ToShortDateString());
}
}
}

至此,我们已经有了IOC思维了。下一步,我们将通过Autofac来实现它。

添加Autofac引用

第一步,需要在项目中添加Autofac的引用。建议通过NuGet方式(如下图),将会自动添加到项目中。

Autofac,除了Core之外,还有很多扩展,例如和ASP.NET MVC集成等等。

截至目前为止,Autofac Core最新版本为4.6.0,对应.net framework 4.5.

应用程序启动

在应用程序启动环节,你需要创建一个ContainerBuilder来注册组件。
一个组件,可以是一个表达式,一个.NET类型,又或者可以是一个或者多个带依赖项的Service等等。

简单来说,如下这个实现接口的.NET类,我们有两种方式来定义它的类型。

public class SomeType : IService
{
}
  • 作为类型自身,那就是SomeType
  • 作为接口,那就是IService

如上的例子,组件就是SomeType,同时也是包括SomeType和IService的两种形态的服务。

在Autofac,你可以按照如下方式向ContainerBuilder注册组件。

// 创建builder.
var builder = new ContainerBuilder(); // 通常情况下,我们感兴趣的是IService:
builder.RegisterType<SomeType>().As<IService>(); // 或者,也可以同时注册IService和SomeType
builder.RegisterType<SomeType>().AsSelf().As<IService>();

对于我们的示例应用程序,我们需要注册所有组件(类),并公开它们的服务(接口),这样就可以很好地连接起来。

我们还需要保存Container,以便以后可以使用它来解析类型。

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<TodayWriter>().As<IDateWriter>();
Container = builder.Build(); // WriteDate在执行时,Autofac将自动根据注册的组件进行装配并执行.
WriteDate();
}
}
}

现在我们有一个Container,所有的组件都已注册,并且它们正在公开适当的服务。让我们利用它吧。

应用程序执行

在应用程序执行,你需要使用你注册的组件时,是通过lifetime scope来解析出相应组件实例的。

Container本身也是一个lifetime scope,从技术角度来说,你可以从Container直接解析出组件,然而并不推荐这样用。

解析一个组件时,将会根据所定义的实例范围,创建一个对象的新实例。(解析一个组件大致相当于调用“new”实例化一个类。很简单的一个类比。),某些组件可能有特殊的Dispose(如组件本身实现了IDisposable)- Autofac可以在lifetime scope终止时也会自动处理这些组件特殊的Dispose。

Container这个lifetime scope,在应用程序执行时会一直存在。所以,如果用Container来解析所有的组件的话,可以想象当应用程序终止时,Dispose将是多么繁忙的景象(所有的组件等待被Dispose),同样,因为直到最后一刻才会被Dispose,会更大几率引发“内存不足”这个问题。

所以,推荐从Container创建一个新的lifetime scope来解析组件,在完成相关执行代码后,lifetime scope连带着组件即可被释放。

(一旦你使用了Autofac integration libraries,创建和使用lifetime scope后就可以完全忘记它)

对于我们的示例应用程序,我们将创建一个lifetime scope,然后解析出writer这个组件,并执行“writedate”方法。

namespace DemoApp
{
public class Program
{
private static IContainer Container { get; set; } static void Main(string[] args)
{
// ......
} public static void WriteDate()
{
// 创建scope, 解析IDateWriter,
// 使用它, 销毁scope.
using (var scope = Container.BeginLifetimeScope())
{
var writer = scope.Resolve<IDateWriter>();
writer.WriteDate();
}
}
}
}

现在运行程序…

  • “writedate”方法要求一个idatewriter。
  • autofac看到idatewriter映射到TodayWriter,开始创建一个todaywriter。
  • autofac看到todaywriter需要ioutput来完成构造。
  • autofac看到ioutput映射到consoleoutput,所以创建一个新的consoleoutput实例。
  • autofac采用新consoleoutput实例完成建设TodayWriter。
  • autofac返回完全构成TodayWriter,可以开始执行“writedate”了。

以后,如果你希望应用程序写另一个日期的话,可以实现一个不同的idatewriter然后改变登记程序的启动。你不需要改变其他的类。是的,这就是IOC(控制反转)!

注意:一般来说,Service很大程度上被认为是一种反模式(看文章)。因此,在你的程序中人工创建scope并使用Container,这种方式不是最好的。使用“Autofac integration libraries”,你通常不需要像示例程序那样人工创建scope。当然,你如何设计应用程序取决于你自己。

本篇结束。

后述:完整的英文版链接在此:http://autofac.readthedocs.io/en/latest/getting-started/index.html,有部分内容没有翻译,也有部分内容自我感觉翻译的并不恰当。若你有意见和建议,可联系我。

本博文属作者原创,首发于www.boxfun.net,除非特别声明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

【翻译Autofac的帮助文档】1.入门指南的更多相关文章

  1. 《KAFKA官方文档》入门指南(转)

    1.入门指南 1.1简介 Apache的Kafka™是一个分布式流平台(a distributed streaming platform).这到底意味着什么? 我们认为,一个流处理平台应该具有三个关键 ...

  2. 翻译qmake文档(一) qmake指南和概述

    翻译qmake文档 目录 英文文档连接: http://qt-project.org/doc/qt-5/qmake-manual.html http://qt-project.org/doc/qt-5 ...

  3. [ Laravel 5.5 文档 ] 快速入门 —— 目录结构篇

    简介 Laravel 默认的目录结构试图为不管是大型应用还是小型应用提供一个良好的起点.当然,你也可以按照自己的喜好重新组织应用的目录结构,因为 Laravel 对于指定类在何处被加载没有任何限制 — ...

  4. Laravel 5.5 文档 ] 快速入门 —— 安装配置篇

    服务器要求 Laravel 框架对PHP版本和扩展有一定要求,不过这些要求 Laravel Homestead 都已经满足了,不过如果你没有使用 Homestead 的话(那真是一件很遗憾的事情),有 ...

  5. [翻译] DTCoreText 从HTML文档中创建富文本

    DTCoreText 从HTML文档中创建富文本 https://github.com/Cocoanetics/DTCoreText 注意哦亲,DTRichTextEditor 这个组件是收费的,不贵 ...

  6. Android开发:《Gradle Recipes for Android》阅读笔记(翻译)6.2——DSL文档

    问题: 你需要查找Android Gradle DSL的完整文档. 解决方案: 访问Gradle Tools网站,从Android开发网站下载ZIP文件. 讨论:Android开发网站首页有完整的AP ...

  7. python sphinx(文档生成器)入门

    简介 Sphinx 是一个 文档生成器 ,您也可以把它看成一种工具,它可以将一组纯文本源文件转换成各种输出格式,并且自动生成交叉引用.索引等.也就是说,如果您的目录包含一堆 reStructuredT ...

  8. Laravel(PHP)使用Swagger生成API文档不完全指南 - 基本概念和环境搭建 - 简书

    在PHPer中,很多人听说过Swagger,部分人知道Swagger是用来做API文档的,然而只有少数人真正知道怎么正确使用Swagger,因为PHP界和Swagger相关的资料实在是太少了.所以鄙人 ...

  9. javacv教程文档手册开发指南汇总篇

    本章作为javacv技术栈系列文章汇总 前言 写了不少关于javacv的文章,不敢说精通 ,只能说对javacv很熟悉.虽然偶尔也提交pull request做做贡献,但是javacv包含的库实在太多 ...

随机推荐

  1. 云计算之路-阿里云上:负载均衡错误修改Cookie造成用户无法登录

    最近陆续有用户反馈在我们网站上登录时遇到登录死循环问题.输入用户名与密码提交后,显示登录成功,但跳转到目标网址后(由于依然处于未登录状态)又跳转回登录页面,再次登录,再次这样...就这样一直循环,怎么 ...

  2. mysql的下载地址+Download WinMD5

    http://dev.mysql.com/downloads/mysql http://www.nullriver.com/products

  3. 详解JS对象

                                          [自定义对象] 1.基本概念 ①对象是包含一系列无序属性和方法的集合: ②键值对:对象中的数据是以键值对的形式存在的,以键取 ...

  4. springcloud(二):注册中心Eureka

    Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service Registry和Service Discovery实现.也是springcloud体系中最重要最核心的组 ...

  5. Maven学习-项目对象模型

    POM包含了四类描述和配置: 项目总体信息:它包含了一个项目的名称,项目的URL,发起组织,以及项目的开发者贡献者列表和许可证. 构建设置:在这一部分,我们自定义Maven构建的默认行为.我们可以更改 ...

  6. .Net程序员学用Oracle系列(27):PLSQL 之游标、异常和事务

    1.游标 1.1.游标属性 1.2.隐式游标 1.3.游标处理及案例 2.异常 2.1.异常类别 2.2.异常函数 2.3.异常处理及案例 3.事务 3.1.开始事务.结束事务 3.2.自治事务 3. ...

  7. `DevOps`相关知识搜集

    本文记录的是搞清楚什么是DevOps过程中检索资料时发现的有价值的帖子. 传送门: 我眼中的DevOps 作者简介:申思维,2005年本科毕业于华南理工大学计算机学院.一直从事Web领域的开发,3年多 ...

  8. 响应式网站-全屏banner响应的2中方法 - 被吃掉的banner

    通常来讲, 设计师们喜欢把banner设计成全屏(1920px或以上) 主题内容控制在一定的范围内一般在1200px左右 这样的设计即可以在宽屏上的表现很好.也能向下兼容一些小屏幕的设备: 如下图(所 ...

  9. 最常用的css垂直居中方法

    css垂直居中一直以来都是一个被大家说烂了的话题,翻来覆去的炒.不过说实话,正是因为css没有提供标准的垂直居中方法(不过在css3中已经有了相关规范),所以大家才会对它进行专门的研究.这研究来研究去 ...

  10. swift学习 - tableView自适应高度2(SnapKit Layout)

    SnapKit是Swift中自动布局的框架,相当于Objective-C中的Masonry 下面是tableView自定义cell,使用SnapKit布局的效果图: 详细代码如下: TYCustomC ...