這裡會介紹 angular 的注入器和例項化過程,基於 [email protected]
angular 依賴注入過程主要有下面幾個重要的部分組成:
angular 依賴注入中的一些重要的概念:
provider :
提供商,下面就是乙個proviver,一共有5種構造提供商的方式:typeprovider, valueprovider, classprovider, existingprovider, factoryprovider
token :
令牌,提供商中的第乙個引數就是token,在查詢依賴時作為 key 使用。
injector :
注入器,用於解析依賴和建立物件。
example
class engine
}class car
open()
}let inj = reflectiveinjector.resolveandcreate([
car,
engine
]);let car = inj.get(car);
car.open();
在上面註解完成之後,接下來可以構造 injector,injector 首先需要解析 provider.
let inj = reflectiveinjector.resolveandcreate([
, ]);
provider 的解析主要由 resolvereflectiveproviders() 來完成,解析過程主要分為
下面是解析過程的原始碼
export function
resolvereflectiveproviders
(providers: provider): resolvedreflectiveprovider
_normalizeproviders 是將 provider 引數標準化,將省略了 useclass 的補全,將巢狀的 provider 陣列拍平
function
_normalizeproviders
(providers: provider, res: provider): provider );
//如果是物件,且帶provide屬性,直接放入陣列
} else
if (b && typeof b == 'object' && (b as any).provide !== undefined) else
if (b instanceof
array) else
});return res;
}
resolvereflectiveprovider 函式會根據 reflectivekey 和 resolvedreflectivefactory 返回乙個 resolvedreflectiveprovider_ 物件。
function
resolvereflectiveprovider
(provider: normalizedprovider): resolvedreflectiveprovider
其中的 resolvereflectivefactory() 函式是其中的重點,解析的例項化工程和以來的方式有4鐘,分別對應 4種 provider 的建立方式,分別是
這個函式裡面會根據這四種方式提供不同的例項化工廠和依賴解析,依賴解析完成會返回乙個 reflectivedependency 陣列。
reflectivedependency 的建構函式為
constructor(
public key: reflectivekey, public optional: boolean,
public visibility: self|skipself|null)
reflectivekey 有兩個屬性: id 和 token ,其內部維持了乙個map
2.2.1 useclass
例項化工廠
useclass 的情況下例項化就通過 new 的方式完成
factoryfn = (...args: any) => new t(...args)
依賴解析方式
從 inject 和 injectable 兩個裝飾器中儲存的資訊尋找依賴的建構函式,也就是從 『parameters』 和 『design:paramtypes』 兩個元資料中尋找。如果當前建構函式沒有,回從原型鏈向上查詢
2.2.2 useexisting
例項化工廠
useexisting 情況下是乙個返回傳入引數的函式,也就是返回依賴的例項
factoryfn = (aliasinstance: any) => aliasinstance;
依賴解析方式
將 useexisting 的值作為其依賴,也就是作為後面例項化時的引數
[reflectivedependency.fromkey(reflectivekey.get(provider.useexisting))]
2.2.3 usefactory
例項化工廠
usefactory 的情況下就是usefactory的值
factoryfn = provider.usefactory;
依賴解析方式
如果定義了 deps,則直接從 deps 中抽取出 token 並構造reflectivedependency
否則使用和 useclass 相同的方法解析依賴
2.2.4 usevalue
例項化工廠
直接返回這個值
factoryfn = () => provider.usevalue;
依賴解析方式
空陣列angular 允許為乙個 token 提供多個 provider, 只要申明 multi:true 即可。
let inj = reflectiveinjector.resolveandcreate([,,
]);let car = inj.get(car); //car = [car, supercar]
此時使用 injector.get() 方法返回的是乙個陣列。 angular 使用這種機制來提供可插拔的介面(pluggable hooks).
mergeresolvedreflectiveproviders() 函式就是用來處理多提供商的情況的,對申明 multi:true 的提供商,它會為乙個 token 提供多個值。
reflectiveinjector 的構造器如下,使用上面解析完成的 resolvedreflectiveprovider_ 和父注入器例項化。
constructor(_providers: resolvedreflectiveprovider, _parent?: injector)
從注入器中獲取物件主要分為以下幾步:
預設是如果當前注入器沒找到,則遞迴向父注入器查詢
self 只從當前注入器查詢
skipself 從父注入器開始查詢
while (inj instanceof reflectiveinjector_)
reflectiveinjector_ 物件中有兩名兩個屬性,主要用於快取物件。 keyids 是所有 reflectivekey 的 id, objs 是快取的已經例項化的物件。
keyids: number;
objs: any;
根據 reflectivekey 的 id 判斷是否已經例項化。 如果沒有就 new 乙個。
private _getobjbykeyid(keyid: number): any
return
this.objs[i];
}} return undefined;
}
例項化物件會首先例項化其需要的依賴,然後再根據由其實例化工廠來處理。
private _instantiate(
provider: resolvedreflectiveprovider,
resolvedreflectivefactory: resolvedreflectivefactory): any catch (e)
throw e;
} let obj: any;
try catch (e)
return obj;
}
angular2 依賴注入新坑。
昨天經理說要改經緯度的格式,然後今天就著手搞。搞了一上午,發現在原有的 input標籤裡做出來有瑕疵。然後,下午就用angular2的 onchanges 監聽來做。做到後面,需要 傳值的時候,自己寫的測試應用就出毛病了。在寫依賴注入服務的時候,檔案引用我是直接寫在 index.ts裡面的,結果,就...
Angular依賴注入例項
先註冊服務shared product 輸入命令 ng g service shared product 生成乙個服務在shared包中 product.service.ts import from angular core injectable 裝飾器 這個productservice也可以通過建...
Angular2筆記(三) 服務與依賴注入
3.服務與依賴注入 a.服務 服務是實現專一目的的邏輯單元,如日誌服務,服務就是乙個普通的類,類裡面定義了一些例項函式,通常使用在元件內部,作為元件功能的乙個擴充套件,使用時需要引入依賴注入 依賴注入 依賴注入是元件引入外部構建 如服務 的一種機制 例如服務,實際上引入的是這個服務的例項 所以服務在...