概述
Angular 2使用自己的依賴注入框架并采用構(gòu)造注入方式尖殃,依賴注入分兩個步驟: 1) 向injector注冊Provider 2) 構(gòu)造類時injector根據(jù)參數(shù)注入對應(yīng)的實(shí)例偷溺。
如上圖所示,注冊時在injector中建立注入名稱和注入實(shí)例的對照表照筑,獲取時根據(jù)注入名稱返回對應(yīng)的注入實(shí)例。在同一injector中瘦陈,注入實(shí)例相當(dāng)于Singleton凝危。
injector可以編碼顯式調(diào)用;Angular 2構(gòu)造時自動獲取注入實(shí)例晨逝,一般地不需要顯式調(diào)用蛾默。
如果服務(wù)依賴于另一個服務(wù),在定義服務(wù)類時需要加@Injectable標(biāo)注捉貌;建議所有服務(wù)均使用@Injectable標(biāo)注支鸡。
Provider
依賴注入注冊有以下三種方式:
1. 注冊類 Class Provider
最常見的類注冊表達(dá)式如[LoggerService]
冬念,是以下表達(dá)式的縮寫:
[new Provider(LoggerService, {useClass: LoggerService })]
參數(shù)含義如下:
第一個參數(shù)是注入名稱(token)
第二個參數(shù)用于產(chǎn)生注入實(shí)例。
可以使用其他類提供注入實(shí)例牧挣,如:
[ provider(LoggerService, { useClass: BetterLogger }) ]
也可以指定注入名稱的別名急前,如:
[ LoggerService , provider(OtherLogger, {useExisting: LoggerService }) ]
2. 注冊值 Value Provider
可以直接指定注入的實(shí)例浸踩,如:
[ provider(LoggerService, { useValue: loggerInstance }) ]
3. 注冊工廠方法 Factory Provider
當(dāng)需要根據(jù)動態(tài)值確定依賴注入的實(shí)例是叔汁,可使用工廠方法注入。
注入名稱 DI Token
以上注入的都是類實(shí)例检碗,注入名稱是類的類型据块。
如果注入的不是類(如字符串、Object或函數(shù))折剃,注入名稱可以是:
常量字符串
OpaqueToken:優(yōu)于在代碼中直接使用常量字符串另假。
在此情況下,構(gòu)造函數(shù)語法如下:
constructor(@Inject(APP_CONFIG) private config: Config) { ... }
層級依賴注入
Angular 2有兩種注冊方式:
bootstrap函數(shù)的第二個參數(shù)
@Component的providers元數(shù)據(jù)
前者創(chuàng)建全局級依賴注入怕犁,整個應(yīng)用一個實(shí)例边篮;后者創(chuàng)建組件級依賴注入,每個組件擁有自己的實(shí)例奏甫。形成的依賴注入樹如下圖所示:[圖片上傳中戈轿。。阵子。(2)]
一般地思杯,組件在自身injector找不到注入名稱時,到父組件injector中查找挠进,直至全局級injector為止色乾。
根據(jù)前面的說明,類注入可以使用其他類提供實(shí)例领突。這意味著在依賴注入樹中暖璧,同名的注入名稱在不同層級可能對應(yīng)到不同類型的實(shí)例。為避免注入錯誤的類型實(shí)例君旦,Angular 2提供以下措施:
構(gòu)造函數(shù)參數(shù)@Host標(biāo)注:表示該參數(shù)的注入查找到該組件的上層宿主元素為止澎办;
@Component標(biāo)注的viewProviders元數(shù)據(jù):本組件使用的注入名稱可以從viewProviders列表查詢。viewProviders對子組件樹不可見于宙,因此如果是某個子組件查詢同名的注入名稱浮驳,則可以繼續(xù)向上層組件查詢。
一般地捞魁,推薦使用@Component providers元數(shù)據(jù)注冊至会;除了通過服務(wù)進(jìn)行組件間交互情況,因?yàn)榻换サ慕M件必須共享同一實(shí)例谱俭。