本篇淺談Autofac架構,內容含括Autofac能做些甚麼、如何註冊Component和Service、如何透過Autofac取得實體類別,以及Autofac物件生命週期的控管。
淺談Autofac架構
Autofac是一套DI的framework,提供了豐富的使用情境,讓我們能透過依賴反轉(IOC)的程式設計原則,來降低程式碼的耦合度。
在Autofac的世界裡,我們稱實體化的物件為Component,而對外公開的介面稱為Service。所以在程式碼裡,各分層、物件之間都是透過介面(Service)做溝通,因此,未來如果需要抽換實體類別(Component)的邏輯就會變得非常單純、簡單。
Autofac的核心主要圍繞在三個層面
- Registering Component
- Resolving Service
- Controlling Scopen and Lifetime
Registering Component
這個階段主要是在將Service和Component註冊對應關係,註冊的方式有很多種情境,包含最基本的指定型別註冊、甚至可以直接掃描Assembly根據裡面的內容來做大量註冊的動作。也許這樣敘述有點難理解,實際看一個例子會清楚些。
首先,先下載Autofac套件。
範例定義一個ICar介面(Service),只公開一個方法是Drive()。再來,定義一個MyCar類別(Component),實作ICar介面。
public interface ICar
{
void Drive();
}
public class MyCar : ICar
{
public void Drive()
{
Console.Write("Drive BMW");
}
}
接下來,透過註冊,把ICar和MyCar關聯起來,下面的範例就是用類別的方式註冊,把MyCar(Component)註冊成ICar(Service)。
var builder = new ContainerBuilder();
builder.RegisterType<MyCar>().As<ICar>();
Resolving Service
雖然已經註冊好ICar和MyCar之間的關係,但到目前為止仍然沒拿到實際的類別。繼續剛剛的例子,透過Autofac,我跟它說我需要一個實際的車子,而且必須是ICar的類型,請Autofac幫我處理,上面那句是白話,講技術一點就是請Autofac Resolving Service給我。Autofac會根據你所註冊的MyCar,將其實體化之後返回,所以我就可以得到一個MyCar的真實車子,然後執行Drive(),就會出現下方Console的內容。
var car = container.Resolve<ICar>();
car.Drive();
Controlling Scopen and Lifetime
以前用new的方式建立物件,使用完畢後,即使不釋放(dispose)該物件,也會有記憶體回收機制來幫忙處理。但使用Autofac處理相依性後,原本new的動作將交由Autofac來處理,所以Autofac會主導此物件的生命週期,原本的記憶體回收機制就不會干涉,物件的釋放由Autofac全權處理。講白話就是,假如沒有釋放Autofac建立的物件,最終將會耗盡所有記憶體。
但也不必太擔心,Autofac本身有提供很多管理物件生命週期的方式,讓物件和記憶體的使用更有效率。以下就簡單介紹一下最基本的用法,使用Using搭配BeginLifetimeScope()來達到效果,在Using的結尾處,括號內的物件都會自動被釋放(dispose)。
using (var scope = container.BeginLifetimeScope())
{
//注意resolve方法須由scope呼叫
var car = scope.Resolve<ICar>();
car.Drive();
}
同場加映
本段落Demo一下相依於介面而非實作的威力。假如現在需求,我不想使用MyCar,而想使用YourCar來當作ICar的實作。只需兩個步驟,首先,當來得多一個YourCar的類別,這免不了。
public class YourCar : ICar
{
public void Drive()
{
Console.Write("Drive LUXGEN");
}
}
只需更改一個地方,將註冊MyCar的地方改成註冊YourCar。
//builder.RegisterType<MyCar>().As<ICar>();
builder.RegisterType<YourCar>().As<ICar>();
實際跑一下程式看看,如下所示,其他地方都無需更改,就達成需求。試想一下,假如系統有大量使用到ICar類別時,那省下的工將會非常多。
小結
本篇主要是要了解Autofac的整體圖像,以及DI所帶來的方便性,後續再深入研究Registering、Resolving、Component Lifetime會輕鬆很多。除此之外,Autofac也有很多整合性的擴充套件,如針對MVC的Autofac.MVC以及WebApi的Autofac.WebApi2,會讓我們更方便的使用Autofac的功能,這就留待後續探討吧。