Autofac是一個 Ioc 容器
眼尖的讀者會發現我把Ioc跟容器這兩個字使用兩個不同顏色
原因是Autofac這個框架其實做到兩個概念.
- IoC(Inversion of Control)
- 管理物件的容器
Autofac框架幫我們實現可以管理物件生命週期並提供依賴注入相對應的物件中
為何使用Autofac在我們專案中?
我們先來看看在專案中常使用的撰寫方式,我們需要讀取使用者資料 透過UserDao
來幫我們完成.
public UserService {
private UserDao _userDao = new UserDao();
public UserModel GetUserById(string Id){
return _userDao.GetUserById(Id);
}
}
_userDao
物件跟依賴UserService
,導致兩個狀況
UserDao
物件掌控於UserService
,假如有其他類別也使用UserDao
物件各自掌控UserDao
物件,這導致許多不必要的資源浪費.- 日後要替換讀取
GetUserById
方式(從db改讀成其他地方 如API) 需要異動全部有建立UserDao
的類別
我們可以使用IoC容器解決上面兩個問題
使用Autofac 容器
一般容器有多種注入方式:建構子注入,屬性注入,參數注入
按照以下四個步驟 簡單使用Autofac
- 建立
ContainerBuilder
物件 - 註冊型別(可限制創建物件生命週期)
- 建立
IContainer
- 取得我們需要的物件.
此範例使用建構子注入方式
//1.建立ContainerBuilder物件
ContainerBuilder builder = new ContainerBuilder();
//2.註冊型別(可限制創建物件生命週期)
builder.RegisterType<UserDao>().As<IUser>();
//3.建立IContainer
IContainer container = builder.Build();
//4.使用IContainer取得我們需要的物件.
IUser user = container.Resolve<IUser>();
我們新建一個IUser
來給UserDao
繼承當作解耦合點(介面可利於日後替換使用)
public interface IUser{
UserModel GetUserById(string Id);
}
public UserService {
private IUser _userDao;
public UserService(IUser userdao){
_userDao = userdao;
}
public UserModel GetUserById(string Id){
return _userDao.GetUserById(Id);
}
}
可能還感受不到IoC容器威力,因為目前依賴的複雜度還沒有太大
目前模組依賴關係 如下UML圖
模組複雜程度像下圖 如果沒有容器幫我們做物件控制管理,想想就覺得可怕
上圖是我Inovce SDK框架的UML圖
其中我們可以發現 ApiBase
這個抽象類別 依賴於 IConfig
介面(日後可能依賴更多其他物件或介面)
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<AppsettingConfig>().As<IConfig>().InstancePerRequest();
builder.RegisterGeneric(typeof(ApiBase<>)).PropertiesAutowired();
builder.RegisterType<InvoiceApiFactory>().InstancePerRequest();
如果使用Autofac我們可不用擔心這些 只需要將被依賴的物件,介面註冊到容器中,剩下配對注入動作容器都會幫我們達成
已上面的例子來說:我只需要用 InvoiceApiFactory
產生繼承ApiBase<>
物件,使用IConfig
將會被容器自動注入其中。
Autofac 常用三種注射方式.
- Constructor injection
- Property injection
- Method injection
constructor injection
Property injection
Method injection
小結:
系統越來越複雜越能表現IoC容器的優勢,如果系統沒那麼複雜其實也不一定要使用他﹐看情境如何
如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^