【写在前面】尝试作完一件工做以外自我以为有意义的一件事,那就从翻译Autofac的帮助文档吧。html
将Autofac集成你的应用程序的步骤一般很简单,通常是:ui
本篇将经过入门指南实现一个简单的Console应用程序,一旦有了基础,后续能够延伸集成WCF、ASP.NET等等。this
先简单解释一下IOC(控制反转)。
一般状况下,类A若须要类B的一些功能,则在类A中须要经过“new”操做来完成建立和使用功能,这样在代码层面就固定住了类A和类B之间的相互依赖关系。这样的“依赖”,在后续的重构或修改时,影响面很大。
而IOC(控制反转)的思惟,则是取消,由类A来建立类B,变动为在执行期间,由IOC容器来根据须要和约定自动建立类B来给类A使用。spa
Martin Fowler有一篇著名的文章,解释何谓IOC,能够点击“连接”查看。.net
在本篇的示例中,咱们将定义一个类,这个类能够输出一些数据;但咱们不想和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来实现它。htm
第一步,须要在项目中添加Autofac的引用。建议经过NuGet方式(以下图),将会自动添加到项目中。对象
Autofac,除了Core以外,还有不少扩展,例如和ASP.NET MVC集成等等。blog
截至目前为止,Autofac Core最新版本为4.6.0,对应.net framework 4.5.
在应用程序启动环节,你须要建立一个ContainerBuilder来注册组件。
一个组件,能够是一个表达式,一个.NET类型,又或者能够是一个或者多个带依赖项的Service等等。
简单来讲,以下这个实现接口的.NET类,咱们有两种方式来定义它的类型。
public class 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(); } } } }
如今运行程序…
之后,若是你但愿应用程序写另外一个日期的话,能够实现一个不一样的idatewriter而后改变登记程序的启动。你不须要改变其余的类。是的,这就是IOC(控制反转)!
注意:通常来讲,Service很大程度上被认为是一种反模式(看文章)。所以,在你的程序中人工建立scope并使用Container,这种方式不是最好的。使用“Autofac integration libraries”,你一般不须要像示例程序那样人工建立scope。固然,你如何设计应用程序取决于你本身。
本篇结束。
后述:完整的英文版连接在此:http://autofac.readthedocs.io/en/latest/getting-started/index.html,有部份内容没有翻译,也有部份内容自我感受翻译的并不恰当。若你有意见和建议,可联系我。
本博文属做者原创,首发于www.boxfun.net,除非特别声明,本做品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。