2014年9月25日 星期四

[iThome 第七屆鐵人賽 03] Autofac基本介紹

在上一篇:IoC基本概念介紹介紹了IoC和DI的概念。在最後提到了,如果沒有一個東西幫我們管理DI,那麼其實整個的彈性設計還是無法彈性起來。

因此在這一篇,我們就來看一下其中一個比較常用的DI Container:Autofac。

DI Container的選擇

其實有很多種DI Container,它們的運作邏輯都差不多,因此假設不希望在自己的專案裡面使用Autofac,完全可以換一個用的習慣的DI Container。

之前在第一篇提到的Fail-Tracker(Github),它裏面使用的就是Structuremap這個DI Container。

如果還沒有選好要用的DI Container,又想要貨比三家,可以參考這篇部落格 IoC Container Benchmark - Performance comparison 看看針對比較常見的.Net DI Container做效能和功能的比較。

Autofac介紹

imageAutofac

  • 官網:http://autofac.org/
  • 文件:http://autofac.readthedocs.org/en/latest/
  • Nuget上面和它有關的package:Nuget網頁搜索
  • Autofac nuget 安裝指令:Install-Package Autofac
  • Autofac 和asp .net mvc 5 整合的nuget 安裝指令:Install-Package Autofac.Mvc5
  • 其他備註:Autofac不止適合用在Mvc裡面,基本上所有類型的.Net他都有對應的整合Helper(就像上面那個就是針對mvc 5的整合helper)。

Autofac 基本概念介紹

基本上來說使用Autofac的流程就是:

Autofac Basic FlowAutofac最基本使用流程圖

第一步,建立ContainerBuilder

在第一步就是建立一個ContainerBuilder的物件。要建立DI Container,你當然需要告訴他什麽東西配對什麽,因此,這個物件會記錄你註冊進去的Service(服務)和Component(元件)- 等一下在有比較詳細介紹這兩個的意思,最後都註冊完了,就建立出一個DI Container。

第二步,註冊服務

第二步就是註冊服務。在Autofac裡面基本上最長看到的應該就是Service和Component:

  • Component:要註冊到Container的類別。Component基本上就是你和DI Container要東西的時候,他會new給你的類別
  • Service:Service就是Component會提供的服務。基本上會是interface(當然,不一定是要interface)。
因此,簡單來看,Service是interface,Component就是interface的實作。因此,在註冊到ContainerBuilder的時候,要告訴他,什麽service(interface),對應到什麽 component(interface實作的class)。

在註冊服務這一邊,Autofac有提供所謂的module,也就是比較複雜或可重複使用的服務註冊可以把它包成一個module,這樣以後註冊起來很方便(Autofac和Mvc的結合也是用了 Module,方便註冊Mvc相關)

在註冊服務這一方面,Autofac提供了很多種的註冊方式,可以由寫C#來註冊,也可以由讀xml來設定註冊,因此非常彈性。

在註冊這一塊其實很多細節,詳細可以參考:Registering Component

第三步,建立Container

第三步就是當我們把要用的service和component都註冊完成了之後,就會呼叫ContainerBuilder.Build()。這個的東西就是我們的DI Container。

最後一步,取得我們要的Component

最後,有了Container,我們就可以透過Container,來取得我們需要的component。

這個在文件裡面稱之為Resolving,相關的使用方法可以參考文件的Resolving Service

Resolving我不會提太多,因為基本上多我們來說是無縫的和Mvc整合,我們不需要自己手動Resolve。因此,之後有需要請參考文件。

Autofac 使用範例

下面的範例是我從官網抄下來,裡面的注解介紹了每一個部份:

// 第一步,建立ContainerBuilder
var builder = new ContainerBuilder();

// 開始 第二步,註冊service

// 註冊ConsoleLogger這個class為ILogger Service的Component
builder.RegisterType<ConsoleLogger>.As<ILogger>();

// 如果寫法是:builder.RegisterType<ConsoleLogger>();
// 那麼就是ConsoleLogger這個class為ConsoleLogger Service的Component

// 註冊自己實例化出來的物件
// 上面是只註冊class type(因此,用到的時候是autofac幫你new出來),這邊是直接用這個object
var output = new StringWriter();
builder.RegisterInstance(output).As<TextWriter>();

// 用lambda 註冊會更有彈性,因為傳進來的c是container的instance,因此可以用c來做一些複雜的東西。
builder.Register(c => new ConfigReader("mysection")).As<IConfigReader>();

// 假設不想要一個一個註冊,可以用scan的方式。
// 下面scan一個assembly所有的type,當那個type的名字最後結尾是Repository的時候,
// 把它註冊的service設為這個class的interface
builder.RegisterAssemblyTypes(myAssembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();

//結束 第二步

// 第三步,註冊都完成了,建立自己的container
var container = builder.Build();

// 第四部,從container取得對應的component。
// 這邊用using包起來,因為出了這個scope,一切Resolve出來的都會被釋放掉。
// 這部份在我們整個系列碰到並不多,因為不建議自己每一個這樣取出來,
// 而是用深度整合的方式來讓一切像自動發生。
// 詳細之後就會比較清楚
using(var scope = container.BeginLifetimeScope())
{
var reader = container.Resolve<IConfigReader>();
}

結語

如果從來沒有使用過DI Container,看到這邊可能還是覺得很抽象,不確定怎麼用。不用擔心,之後我們在開發框架的時候會使用到,到時候在回來比照前面這些內容,相信因該會給一個不錯的起始點。

Autofac其實細部有很多內容,我這邊只碰到了最基礎的部份,希望透過這一篇能夠打開DI Container和Autofac的一些學習曲綫,給予一個好的起始點,之後要查找問題能夠更容易一些。

本來這一篇會介紹到Autofac如何和Asp .net Mvc整合,但在寫下去怕太長,因此Mvc的部份就留到下一次在講。

Reference

再次總結一下相關資源:

沒有留言 :

張貼留言