.NET手记-Autofac入门Getting Started

内容主要翻译自官方文档,原文请看:http://autofac.readthedocs.org/en/latest/getting-started/index.html#application-startup

将Autofac集成进你的应用的基本模式:

  • 在脑海中构造基于控制反转(IoC)的应用程序架构
  • 添加Autofac引用.
  • 在应用启动配置流程...
  • 创建一个 ContainerBuilder.
  • 注册组件(components).
  • build定义的ContainerBuilder生成Autofac容器,并存储它以供后续使用.
  • 在程序运行时...
  • 从Autofac容器(container)创建生命周期域(lifetime scope).
  • 使用生命周期域来解析出组件实例.

这篇指导将会使用一个控制台程序一步一步演示如何使用Autofac. 一旦你有了基础的了解,可以到以下wiki站点查看更高级的使用方法和技巧: integration information for WCF, ASP.NET, and other application types.

构建应用架构

基于IoC的想法应该是对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它,而不是把所有类绑在一起,每次都要通过依赖new来传递实例.如果你想了解更多请看:Martin Fowler has an excellent article explaining dependency injection/inversion of control.

对于我们的示例应用程序,我们将定义一个输出当前日期的类。但是,我们不希望它和控制台绑在一起,因为我们希望以后能够测试它或用在一个没有控制台程序的地方。
我们还会去尽量抽象输出日期的机制,以便于我们后续重复使用。
我们会做这样的事情:

using System;

namespace DemoApp
{
  // This interface helps decouple the concept of
  // "writing output" from the Console class. We
  // don‘t really "care" how the Write operation
  // happens, just that we can write.
  public interface IOutput
  {
    void Write(string content);
  }

  // This implementation of the IOutput interface
  // is actually how we write to the Console. Technically
  // we could also implement IOutput to write to Debug
  // or Trace... or anywhere else.
  public class ConsoleOutput : IOutput
  {
    public void Write(string content)
    {
      Console.WriteLine(content);
    }
  }

  // This interface decouples the notion of writing
  // a date from the actual mechanism that performs
  // the writing. Like with IOutput, the process
  // is abstracted behind an interface.
  public interface IDateWriter
  {
    void WriteDate();
  }

  // This TodayWriter is where it all comes together.
  // Notice it takes a constructor parameter of type
  // IOutput - that lets the writer write to anywhere
  // based on the implementation. Further, it implements
  // WriteDate such that today‘s date is written out;
  // you could have one that writes in a different format
  // or a different date.
  public class TodayWriter : IDateWriter
  {
    private IOutput _output;
    public TodayWriter(IOutput output)
    {
      this._output = output;
    }

    public void WriteDate()
    {
      this._output.Write(DateTime.Today.ToShortDateString());
    }
  }
}

添加Autofac引用

首先添加Autofac引用到你的项目,这个例子中我们仅添加Autofac Core引用,其他类型应用程序可能会用到不同的Autofac.Integration类库。

通过NuGet可以很容易为项目引入引用,如图:

应用启动(Application Startup)

在???启动时,你需要创建一个ContainerBuilder并使用它注册各种组件. 组件可以是表达式、.NET类型或者一些用于暴露内部服务的代码。

简单的来说,有个实现了接口的类型,如下:

public class SomeType : IService
{
}

你可以通过两种方式定位到它:通过类型SomeType,或者通过接口IService.

在这个例子中,组件是SomeType,同时暴露的服务是指SomeType类型和IService接口。

在Autofac中,你应该通过ContainerBuilder来注册它们。

// Create your builder.
var builder = new ContainerBuilder();

// Usually you‘re only interested in exposing the type
// via its interface:
builder.RegisterType<SomeType>().As<IService>();

// However, if you want BOTH services (not as common)
// you can say so:
builder.RegisterType<SomeType>().AsSelf().As<IService>();

对于我们的示例应用程序,我们需要注册我们所有的组件(类),并暴露他们的服务(接口)。

我们还需要存储容器,这样它之后可用于解析出各种类型实例。

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();

      // The WriteDate method is where we‘ll make use
      // of our dependency injection. We‘ll define that
      // in a bit.
      WriteDate();
    }
  }
}

这样我们就拥有了一个注册了所有组件的容器,这些组件同时暴露了它们的服务。现在让我们来使用这个容器。

应用运行时

在应用运行期间,你需要从容器生命周期域中解析出组件实例来使用它们。容器自身就是一个生命周期域(lifetime scope),技术上来讲,你可以直接从容器中解析出需要的组件。

但是我们不推荐直接操作容器,这会导致内存泄漏。

当我们解析出一个组件时,依赖于我们定义的lifetime scope,一个新的对象实例会被创建。其中一些组件可能需要被释放,例如实现IDispose接口的对象。当生命周期域被释放时,Autofac可以自动处理组件资源的释放。

但是容器存在于整个应用程序生命周期。如果你直接从容器中解析出大量组件,可能会导致很多组件一直等待被释放。这样做法并不好,通常会导致内存泄露。

替代方案是,每次我们从容器来创建子生命周期域,。当你从子域完成解析组件后,子域将会被释放,同时所有资源都会被清理掉。

对于我们的示例程序来说,我们将会从子域中解析出IDateWriter实例,并运行WriterDate()方法。同时在我们完成后,子域将会被释放。

namespace DemoApp
{
  public class Program
  {
    private static IContainer Container { get; set; }

    static void Main(string[] args)
    {
      // ...the stuff you saw earlier...
    }

    public static void WriteDate()
    {
      // Create the scope, resolve your IDateWriter,
      // use it, then dispose of the scope.
      using (var scope = Container.BeginLifetimeScope())
      {
        var writer = scope.Resolve<IDateWriter>();
        writer.WriteDate();
      }
    }
  }
}

现在当你运行你的程序时...

  • WriteDate()方法从Autofac中请求IDateWriter实例.
  • Autofac发现IDateWriter可以映射到TodayWriter类型,所以创建了一个TodayWriter实例.
  • Autofac发现TodayWriter在它的构造函数中需要一个IOutput实例.
  • Autofac发现IOutput 可以映射到ConsoleOutput,所以创建了一个ConsoleOutput新实例.
  • Autofac使用ConsoleOutput实例完成构造一个TodayWriter实例.
  • Autofac返回了一个完全构造好的TodayWriter实例来用于“WriteDate” 方法.

之后,如果你的程序想要实现输出不同日期, 你可以构造不同实现IDateWriter接口的类型,同时在应用启动时注册. 你不必改变其他任何的类. 这就是控制反转!

注意:正常来说service location很大程度上被认为是反模式。也就是说,到处手动创建域(scope)和大量使用容器不一定是最好的方案。使用Autofac你通常不必做我们在示例应用中的做的事情。组件会从一个应用的中心或者顶层来解析,手写的解决方案很罕见的。当然,如何设计应用程序是由你自己决定的。

时间: 2024-08-03 23:03:25

.NET手记-Autofac入门Getting Started的相关文章

一、Autofac入门

想要将autofac集成到你的应用程序中需要经过如下步骤: 1.使用控制翻转(IoC)的思想架构你的应用程序: 2.添加autofac引用: 3.在应用程序入口...(At application startup...): 4.创建一个ContainerBuilder对象: 5.注册组件: 6.为以后的使用,生成并保存容器: 7.在应用执行期间...(During application execution...): 8.从容器中创建一个生命周期域: 9.使用生命周期域解析(resolve)组件

《Python核心编程 》手记-快速入门

春节终于over了,回归充实的学习研究生活.打开久违的CSDN博客,看到官方推送的 『博客Markdown编辑器上线啦』,让我顿时有了写作的欲望,真是程序员的福利.之前阅读各种文章书籍,都是用MarkDownPad做的笔记,喜欢以及习惯于MarkDown简洁的语法. 总之各种方便.为了试试效果,将以前阅读<Python核心编程>的手记整理发上来,也当温习一遍. 第二章 快速入门 print语句中使用字符串格式操作符,实现字符替换功能. print "%s is %d" %(

Autofac 一个使用Demo

一:接口 二:实现: 三:调用: 首先上图: 一:接口代码 public interface IPersonDa { PersonEntity Get(int id); } 二:实现 public class PersonDa : IPersonDa { public PersonEntity Get(int id) { using (BaseMgr.BaseSysDbContext db = new BaseSysDbContext()) { var result = db.People.Wh

不复杂的Autofac注入

private static void SetAutofacWebAPI() { var builder = new ContainerBuilder(); #region 配置注册方法 string dataType = ConfigurationManager.AppSettings["dataBaseType"].ToString().ToLower(); //var data = Assembly.Load("Model");//加载特定程序集 var da

【AutoFac】依赖注入和控制反转的使用

在开始之前首先解释一下我认为的依赖注入和控制反转的意思.(新手理解,哪里说得不正确还请指正和见谅) 控制反转:我们向IOC容器发出获取一个对象实例的一个请求,IOC容器便把这个对象实例“注入”到我们的手中,在这个时候我们不是一个创建者,我们是以一个请求者的身份去请求容器给我们这个对象实例.我们所有的对象依赖于容器提供给你的资源,控制权落到了容器身上.在这里的身份转化或许就是控制反转的核心吧. 依赖注入:我们向容器发出请求以后,获得这个对象实例的过程就叫依赖注入.也就是我们在使用对向前我们都需要先

Autofac总结

Autofac 介绍|术语 控制反转:IOC和DI IOC 调用者不再创建(不自己new)被调用者的实例,而是交给容器去创建(AutoFac就充当这里的容器),这就是控制反转 控制反转中引入的第三方对象,通过Ioc容器将对象与对象的关系进行解耦,对象的创建与维护让渡给第三方容器 Ioc容器负责维护对象与对象之间的关系,并负责对象的创建和对象生命周期的维护 DI 容器创建好的实例再注入调用者的过程,就是依赖注入(比如:属性注入.构造函数注入等) 依赖注入就是将实例变量传入到一个对象中去 控制反转和

IOC框架之AutoFac简介

一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌似更为普遍,于是捯饬了两天,发现这个东东确实是个高大上的IOC容器~ Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个: 优点: 它是C#语言联系很紧密,也就是说C#里的很多编程方式都可以为Autofac使用,例如可以用Lambda表达式注册组件 较低的学习曲线,学习它非常的简单,只要你理解了IoC和DI的概念以及在何时需要使用它们 XML配置支持 自动

【翻译Autofac的帮助文档】1.入门指南

[写在前面]尝试做完一件工作之外自我觉得有意义的一件事,那就从翻译Autofac的帮助文档吧. 入门指南 将Autofac集成你的应用程序的步骤通常很简单,一般是: 时刻以IOC(控制反转)的思想来规划你的应用程序 在你的Porject中添加Autofac引用 按照如下步骤设计应用程序的启动环节 创建一个ContainerBuilder 向ContainerBuilder注册组件 通过ContainerBuilder的Build()方法获得Container(后续需用到) 在应用程序运行环节时,

.NET手记-Autofac进阶Registering Components

通过创建ContainerBuilder并配置暴露的service(接口或者类型)来使用Autofac注册我们的组件. 组件(Components) 可以通过反射, 提供对象实例化,或者通过lambda表达式来创建. ContainerBuilder有一系列的Register()方法来实现组件的注册. ContainerBuilder中每个组件都能通过As()方法来暴露他们一个或多个service. // Create the builder with which components/serv