Autofac 是一種幫忙管理物件注入的容器,能夠幫助我們在 Controller 建構式注入物件,這樣才有辦法與實體隔離,幫助我們寫單元測試。 今天就來說明怎麼設定 Autofac 使 Controller 建構式注入物件。 今天會以 Web API 為例子。(要注意:MVC的註冊方式有點不同)

使用容器註冊物件

為了方便整理,我會先新增 AutofacConfig.cs 放在 App_Start 資料夾裡面, AutofacConfig.cs 則負責註冊。

  • 安裝 Autofac.WebAPi2
  • 先註冊所有 Web API Controller 到 ContainerBuilder
  • 註冊所有 Controller 要相依的物件,這邊以 IConfiguration 為例子,表示 Controller 建構式注入 IConfiguration 時會取得 Configuration 物件
  • 開啟 Global.asax.cs 加入 AutofacConfig.Bootstrapper()
    AutofacConfig
    • cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public class AutofacConfig
    {
    public static void Bootstrapper()
    {
    var builder = new ContainerBuilder();

    // Get your HttpConfiguration.
    var config = GlobalConfiguration.Configuration;

    // Register your Web API controllers.
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    // OPTIONAL: Register the Autofac filter provider.
    builder.RegisterWebApiFilterProvider(config);

    builder.RegisterType<Configuration>()
    .As<IConfiguration>()
    .InstancePerLifetimeScope();

    builder.RegisterType<Configuration>()
    .As<IConfiguration>()
    .InstancePerLifetimeScope();

    var container = builder.Build();

    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    }
    }

打開 Global.asax.cs 加入 AutofacConfig.Bootstrapper();

Global.asax.cs
  • cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);

// 加入這行
AutofacConfig.Bootstrapper();

}
}

接下來 Controller 就可以建構式注入 IConfiguration 取得 Configuration 物件

Controller
  • cs
1
2
3
4
5
6
7
8
public class ValuesController : ApiController
{
IConfiguration _configuration;
public ValuesController(IConfiguration configuration)
{
_configuration = configuration;
}
}

建立 Autofac.Module

當註冊物件一多的時候,我們可以建立 Aufofac.Module 把註冊這件事情分散在各個 Module 處理。

例如我建立一個 EFModule ,註冊 Entities。

EFModule
  • cs
1
2
3
4
5
6
7
8
9
public class EFModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<WebPaymentEntities>()
.As<WebPaymentEntities>()
.InstancePerLifetimeScope();
}
}

我的 ContainerBuilder 只要註冊 Module 就好

Register Module
  • cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void Bootstrapper()
{
var builder = new ContainerBuilder();

// Get your HttpConfiguration.
var config = GlobalConfiguration.Configuration;

// Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

// OPTIONAL: Register the Autofac filter provider.
builder.RegisterWebApiFilterProvider(config);

builder.RegisterType<Configuration>()
.As<IConfiguration>()
.InstancePerLifetimeScope();

// 註冊 Module
builder.RegisterModule(new EFModule());

var container = builder.Build();

config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}

一次註冊多個物件

在寫 MVC 或 Web API 的時候可以常見到 Repository Pattern 而 Repository Pattern 有一定的命名規格,例如: 介面 IxxxRepository 會對應到一個類別 xxxRepository

Repository
  • cs
1
2
3
4
5
6
7
8
9
10
public class ProductRepository : IProductRepository
{
private WebPaymentEntities context;

public ImportContainerRepository(WebPaymentEntities context)
{
this.context = context;
}

}

我們就可以用這命名的 Pattern 建立一個 Autofac Module 註冊所有的 Repository

Respository Module
  • cs
1
2
3
4
5
6
7
8
9
10
public class RepositoryModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(typeof(WebApiApplication).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
}

小結

通常 Autofac 設定一次就很少再設定了,所以沒有研究很深,就先筆記到這邊,等之後需要其他應用的時候,再來詳細閱讀官方文件。

參考

Autofac 官方文件