• 通常使用 Action Filter 的時候常常會用到一些資料庫的讀取,為了防止耦合性過高,所以建立取得 DBContext 實體的時候,可以用 DI 的方式注入。
  • MVC 會很常用到 HttpContextBase 、 RequestContext 等等之類功能,所以也建議這些也可以用 DI 的方式注入。

簡短說明一下,此範例以 ASP.NET MVC5 為例,且在使用 Autofac 之前要先安裝 Autofac.MVC5。 若完全不懂 DI 可以參考這篇 Autofac 設定 Web API Register Controller 筆記 或者參考 Autofac 官方文件

其實根據 Autofac官方文件 ,已經說明得很清楚了,重點就 2 行程式碼

  • 註冊 Web abstraction class : builder.RegisterModule<AutofacWebTypesModule>();
  • Action Filter 啟用 Property Injection : builder.RegisterFilterProvider();
Application_Start
  • 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
29
30
31
32
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);

// 開始建立 Container
var builder = new ContainerBuilder();

// Register your MVC controllers. (MvcApplication is the name of
// the class in Global.asax.)
builder.RegisterControllers(typeof(MvcApplication).Assembly);

builder.RegisterType<DateService>()
.As<IDateService>()
.InstancePerLifetimeScope();

// OPTIONAL: 註冊 web abstractions
builder.RegisterModule<AutofacWebTypesModule>();

// OPTIONAL: 啟用 property injection into action filters.
builder.RegisterFilterProvider();

// Set the dependency resolver to be Autofac.
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

}
}

測試結果

成功取得 HttpContextBase 實體

Inject HttpContextBaseInject HttpContextBase

成功 Property Injection

Property InjectionProperty Injection

AutofacWebTypesModule 註冊的 abstraction classes

註冊 AutofacWebTypesModule 會把很多 MVC 用到的 abstraction class 註冊進去,其中註冊了哪類別,可參考 官方文件 - register web abstractions

啟用 Property Injection

使用 builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired() 啟用 Property Infjection,只要透過 Autofac Container 建立的物件,只要加入這一段,就可以從 Property 注入實體。

Application_Start
  • 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
29
30
31
32
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);

// 開始建立 Container
var builder = new ContainerBuilder();

// Register your MVC controllers. (MvcApplication is the name of
// the class in Global.asax.)
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
builder.RegisterType<DateService>()
.As<IDateService>()
.InstancePerLifetimeScope();

// OPTIONAL: 註冊 web abstractions
builder.RegisterModule<AutofacWebTypesModule>();

// OPTIONAL: 啟用 property injection into action filters.
builder.RegisterFilterProvider();

// Set the dependency resolver to be Autofac.
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

}
}

參考

Autofac, Autofac 建立 Container git 範例