Autofac入门

“Autofac is an addictive IoC container for .NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity. This is achieved by treating regular .NET classes as components.” — Autofac.

至于什么是IoC (Inversion of Control),什么是DI (Dependency Injection),不在本文讨论范围。

举个例子,比如你有两个类Service1和Service2,都继承了接口IService。每次你要调用IService时,你得先初始化一个Service1或者Service2的对象。

IService service = new Service1();
// 或
IService service = new Service2();
service.DoSth();

有了autofac,service的初始化就从主业务逻辑里挪到了别的地方。用的时候,说一句我需要一个IService对象,一切就都准备好了。

6个key words

  • Component
    这时最基本的一个概念,就是你需要用到的那个东西,比如上面说的service。
    “A component is an expression, .NET type, or other bit of code that exposes one or more services and can take in other dependencies.”
  • Resolve
    取得Component称为Resolve。
  • Register
    Autofac不可能凭空知道你要做什么,所以在Resolve的时候,相关的Component必须要登记在册,即Register。
  • Container
    IoC使得产生的components不再depend on使用他们的对象,于是也必须有一个容器来盛放、管理他们。这个容器就是Container。
  • Scope
    Container的lifetime通常是整个application。如果所有的component都直接挂载在这个container上的话,无疑会造成内存泄漏。所以可以把components挂载到container不同lifetime的scope上。
    “The container itself is a lifetime scope, and you can technically just resolve things right from the container. It is not recommended to resolve from the container directly, however.
    When you resolve a component, depending on the instance scope you define, a new instance of the object gets created.However, the container lives for the lifetime of your application. If you resolve a lot of stuff directly from the container, you may end up with a lot of things hanging around waiting to be disposed.
    Instead, create a child lifetime scope from the container and resolve from that. When you’re done resolving components, dispose of the child scope and everything gets cleaned up for you.”
  • ContainerBuilder
    ContainerBuilder用来register components并create 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();

      // The WriteDate method is where we'll make use
      // of our dependency injection.
      WriteDate();
    }

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

Leave a comment