您好,登錄后才能下訂單哦!
在介紹 Angular Injector (注入器) 之前,我們先要了解 Dependency Injection,即依賴注入的概念。
依賴注入允許程序設計遵從依賴倒置原則 (簡單的說就是要求對抽象進行編程,不要對實現進行編程,這樣就降低了客戶端與實現模塊間的耦合) 調用者只需知道服務的接口,具體服務的查找和創建由注入器 (Injector) 負責處理并提供給調用者,這樣就分離了服務和調用者的依賴,符合低耦合的程序設計原則。
從上述的內容可知,依賴注入中包含三種角色:調用者、服務和注入器 (Injector)。現在我們開始介紹 Injector,在 Angular 中 Injector (注入器) 用來管理服務對象的創建和獲取。接下來我們先來看一下 Injector 抽象類:
Injector 抽象類
// angular2\packages\core\src\di\injector.ts export abstract class Injector { static THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND; static NULL: Injector = new _NullInjector(); /** * 用于根據給定的Token從注入器中獲取相應的對象。 * 如果沒有找到相應的對象,將返回notFoundValue設置的值。若notFoundValue的值與 * _THROW_IF_NOT_FOUND相等,則會拋出異常。 */ abstract get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T): T; } const _THROW_IF_NOT_FOUND = new Object();
Injector 抽象類中定義了一個 get()
抽象方法,該方法用于根據給定的 Token 從注入器中獲取相應的對象,每個Injector 抽象類的子類都必須實現該方法。在 Angular 中常見的 Injector 抽象類子類有:
下面我們來依次介紹它們:
_NullInjector 類
_NullInjector 類的實例用于表示空的注入器。
// angular2\packages\core\src\di\injector.ts class _NullInjector implements Injector { get(token: any, notFoundValue: any = _THROW_IF_NOT_FOUND): any { if (notFoundValue === _THROW_IF_NOT_FOUND) { throw new Error(`No provider for ${stringify(token)}!`); } return notFoundValue; } }
ReflectiveInjector 抽象類
ReflectiveInjector 表示一個依賴注入容器,用于實例化對象和解析依賴。
ReflectiveInjector 使用示例
@Injectable() class Engine {} @Injectable() class Car { constructor(public engine:Engine) {} } var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]); var car = injector.get(Car); expect(car instanceof Car).toBe(true); expect(car.engine instanceof Engine).toBe(true);
上面示例中,我們通過調用 ReflectiveInjector 抽象類的 resolveAndCreate()
方法,創建注入器。然后通過調用注入器的 get()
方法,獲取 Token 對應的對象。該抽象類除了 resolveAndCreate()
靜態方法外,還含有以下靜態方法:
接下來我們來分析上述的靜態方法:
resolveAndCreate()
static resolveAndCreate(providers: Provider[], parent?: Injector): ReflectiveInjector { const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers); return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent); }
從上面代碼中,我們可以看出 resolveAndCreate()
方法內部是通過調用 ReflectiveInjector.resolve()
方法和 ReflectiveInjector.fromResolvedProviders()
方法來創建 ReflectiveInjector 對象。
resolve()
該方法用于把 Provider 數組解析為 ResolvedReflectiveProvider 數組。
static resolve(providers: Provider[]): ResolvedReflectiveProvider[] { return resolveReflectiveProviders(providers); }
resolve() 使用示例
@Injectable() class Engine {} @Injectable() class Car { constructor(public engine:Engine) {} } var providers = ReflectiveInjector.resolve([Car, [[Engine]]]); expect(providers.length).toEqual(2); expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true); expect(providers[0].key.displayName).toBe("Car"); expect(providers[1].key.displayName).toBe("Engine");
resolve() 解析圖示
Provider 類型
export type Provider = TypeProvider | ValueProvider | ClassProvider | ExistingProvider | FactoryProvider | any[]; // ApiService export interface TypeProvider extends Type<any> {} // { provide: ApiService, useClass: ApiService } export interface ClassProvider { // 用于設置與依賴對象關聯的Token值,Token值可能是Type、InjectionToken、OpaqueToken的實例或字符串 provide: any; useClass: Type<any>; // 用于標識是否multiple providers,若是multiple類型,則返回與Token關聯的依賴對象列表 multi?: boolean; } // { provide: 'API_URL', useValue: 'http://my.api.com/v1' } export interface ValueProvider { provide: any; useValue: any; multi?: boolean; } // { provide: 'ApiServiceAlias', useExisting: ApiService } export interface ExistingProvider { provide: any; useExisting: any; multi?: boolean; } // { provide: APP_INITIALIZER, useFactory: configFactory, deps: [AppConfig], multi: true } export interface FactoryProvider { provide: any; useFactory: Function; deps?: any[]; // 用于設置工廠函數的依賴對象 multi?: boolean; }
ResolvedReflectiveProvider 接口
export interface ResolvedReflectiveProvider { // 唯一的對象用來從ReflectiveInjector中獲取對象 key: ReflectiveKey; // 工廠函數用于創建key相關的依賴對象 resolvedFactories: ResolvedReflectiveFactory[]; // 標識當前的provider是否為multi-provider multiProvider: boolean; }
ResolvedReflectiveFactory 類
export class ResolvedReflectiveFactory { constructor( public factory: Function, public dependencies: ReflectiveDependency[]) {} }
ReflectiveDependency 類
export class ReflectiveDependency { constructor( public key: ReflectiveKey, public optional: boolean, public visibility: Self|SkipSelf|null) {} static fromKey(key: ReflectiveKey): ReflectiveDependency { return new ReflectiveDependency(key, false, null); } }
ReflectiveKey 類
ReflectiveKey 對象中包含兩個屬性:系統范圍內唯一的id 和 token。系統范圍內唯一的id,允許注入器以更高效的方式存儲已創建的對象。另外我們不能手動的創建 ReflectiveKey,當 ReflectiveInjector 對象解析 providers 的時候會自動創建 ReflectiveKey 對象。
export class ReflectiveKey { constructor(public token: Object, public id: number) { if (!token) { throw new Error('Token must be defined!'); } } // 返回序列化的token get displayName(): string { return stringify(this.token); } // 獲取token對應的ReflectiveKey static get(token: Object): ReflectiveKey { return _globalKeyRegistry.get(resolveForwardRef(token)); } // 獲取系統中已注冊ReflectiveKey的個數 static get numberOfKeys(): number { return _globalKeyRegistry.numberOfKeys; } } const _globalKeyRegistry = new KeyRegistry(); // 創建Key倉庫 export class KeyRegistry { private _allKeys = new Map<Object, ReflectiveKey>(); /** * 若token是ReflectiveKey類的實例,則直接返回。若_allKeys對象中包含token屬性 * 則返回token對應的ReflectiveKey對象。否則創建一個新的ReflectiveKey對象,并 * 保存到_allKeys對象中 */ get(token: Object): ReflectiveKey { if (token instanceof ReflectiveKey) return token; if (this._allKeys.has(token)) { return this._allKeys.get(token) !; } const newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys); this._allKeys.set(token, newKey); return newKey; } // 獲取已保存ReflectiveKey的個數 get numberOfKeys(): number { return this._allKeys.size; } }
分析完 resolve()
方法的輸入參數和返回類型,我們來看一下該方法內部的具體實現:
export function resolveReflectiveProviders(providers: Provider[]) : ResolvedReflectiveProvider[] { const normalized = _normalizeProviders(providers, []); // 步驟一 const resolved = normalized.map(resolveReflectiveProvider); // 步驟二 const resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map()); // 步驟三 return Array.from(resolvedProviderMap.values()); // 步驟四 }
步驟一 —— 規范化Provider
const normalized = _normalizeProviders(providers, []); // 規范化Providers function _normalizeProviders(providers: Provider[], res: Provider[]): Provider[] { providers.forEach(b => { // providers: [Type] => providers: [{provide: Type, useClass: Type }] if (b instanceof Type) { res.push({provide: b, useClass: b}); } else if (b && typeof b == 'object' && (b as any).provide !== undefined) { res.push(b as NormalizedProvider); } else if (b instanceof Array) { // 若b是數組,則遞歸調用_normalizeProviders()方法 _normalizeProviders(b, res); } else { throw invalidProviderError(b); } }); return res; } interface NormalizedProvider extends TypeProvider, ValueProvider, ClassProvider, ExistingProvider, FactoryProvider {}
步驟二 —— 轉化NormalizedProvider為ResolvedReflectiveProvider
const resolved = normalized.map(resolveReflectiveProvider); // 解析NormalizedProvider為ResolvedReflectiveProvider function resolveReflectiveProvider(provider: NormalizedProvider): ResolvedReflectiveProvider { return new ResolvedReflectiveProvider_( ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false); } // 用于創建已解析的Provider實例 export class ResolvedReflectiveProvider_ implements ResolvedReflectiveProvider { constructor( public key: ReflectiveKey, public resolvedFactories: ResolvedReflectiveFactory[], public multiProvider: boolean) {} get resolvedFactory(): ResolvedReflectiveFactory { return this.resolvedFactories[0]; } } // 解析NormalizedProvider對象,創建ResolvedReflectiveFactory對象 function resolveReflectiveFactory(provider: NormalizedProvider): ResolvedReflectiveFactory { let factoryFn: Function; let resolvedDeps: ReflectiveDependency[]; if (provider.useClass) { // { provide: ApiService, useClass: ApiService } const useClass = resolveForwardRef(provider.useClass); factoryFn = reflector.factory(useClass); resolvedDeps = _dependenciesFor(useClass); } else if (provider.useExisting) { // { provide: 'ApiServiceAlias', useExisting: ApiService } factoryFn = (aliasInstance: any) => aliasInstance; resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))]; } else if (provider.useFactory) { // { provide: APP_INITIALIZER, useFactory: configFactory, deps: [AppConfig], // multi: true } factoryFn = provider.useFactory; resolvedDeps = constructDependencies(provider.useFactory, provider.deps); } else { // { provide: 'API_URL', useValue: 'http://my.api.com/v1' } factoryFn = () => provider.useValue; // const _EMPTY_LIST: any[] = []; resolvedDeps = _EMPTY_LIST; } return new ResolvedReflectiveFactory(factoryFn, resolvedDeps); }
步驟三 —— 合并已解析的Provider
const resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map()); export function mergeResolvedReflectiveProviders( providers: ResolvedReflectiveProvider[], normalizedProvidersMap: Map<number, ResolvedReflectiveProvider>): Map<number, ResolvedReflectiveProvider> { for (let i = 0; i < providers.length; i++) { const provider = providers[i]; // 從normalizedProvidersMap對象中獲取key.id對應的ResolvedReflectiveProvider對象 const existing = normalizedProvidersMap.get(provider.key.id); if (existing) { // 如果當前的provider不是multi provider,則拋出異常 if (provider.multiProvider !== existing.multiProvider) { throw mixingMultiProvidersWithRegularProvidersError(existing, provider); } // 如果當前的provider是multi provider,則把當前provider的resolvedFactories // 列表中的每一項添加到已存在的provider對象的resolvedFactories列表中。 if (provider.multiProvider) { for (let j = 0; j < provider.resolvedFactories.length; j++) { existing.resolvedFactories.push(provider.resolvedFactories[j]); } } else { // 如果當前的provider不是multi provider,則覆蓋已存在的provider normalizedProvidersMap.set(provider.key.id, provider); } } else { let resolvedProvider: ResolvedReflectiveProvider; // 如果當前的provider是multi provider,則創建一個新的ResolvedReflectiveProvider對象 if (provider.multiProvider) { resolvedProvider = new ResolvedReflectiveProvider_( provider.key, provider.resolvedFactories.slice(), provider.multiProvider); } else { resolvedProvider = provider; } // 在normalizedProvidersMap中保存已解析的ResolvedReflectiveProvider對象 normalizedProvidersMap.set(provider.key.id, resolvedProvider); } } return normalizedProvidersMap; }
步驟四 —— 生成ResolvedReflectiveProvider[]
// resolvedProviderMap的values,創建ResolvedReflectiveProvider[] Array.from(resolvedProviderMap.values()); /** * 基于一個類似數組或可迭代對象創建一個新的數組實例 * * arrayLike:轉換成真實數組的類數組對象或可遍歷對象。 * mapFn(可選):如果指定了該參數,則最后生成的數組會經過該函數的加工處理后再返回。 * thisArg(可選):執行mapFn函數時this的值。 */ Array.from(arrayLike[, mapFn[, thisArg]])
fromResolvedProviders()
該方法用于基于已解析的 providers 創建注入器。
static fromResolvedProviders(providers: ResolvedReflectiveProvider[], parent?: Injector): ReflectiveInjector { return new ReflectiveInjector_(providers, parent); }
fromResolvedProviders() 使用示例
@Injectable() class Engine {} @Injectable() class Car { constructor(public engine:Engine) {} } var providers = ReflectiveInjector.resolve([Car, Engine]); var injector = ReflectiveInjector.fromResolvedProviders(providers); expect(injector.get(Car) instanceof Car).toBe(true);
了解完 fromResolvedProviders()
方法的使用方式,接下來我們來重點分析一下 ReflectiveInjector_
類。
ReflectiveInjector_ 類
ReflectiveInjector_ 類的屬性
// 構造次數 _constructionCounter: number = 0; // ResolvedReflectiveProvider列表 public _providers: ResolvedReflectiveProvider[]; // 父級注入器 public _parent: Injector|null; // ReflectiveKey id列表 keyIds: number[]; // 依賴對象列表 objs: any[];
ReflectiveInjector_ 構造函數
export class ReflectiveInjector_ implements ReflectiveInjector { constructor(_providers: ResolvedReflectiveProvider[], _parent?: Injector) { this._providers = _providers; // 設置父級注入器 this._parent = _parent || null; const len = _providers.length; this.keyIds = new Array(len); this.objs = new Array(len); // 初始化keyIds列表和objs對象列表 for (let i = 0; i < len; i++) { this.keyIds[i] = _providers[i].key.id; this.objs[i] = UNDEFINED; } } } const UNDEFINED = new Object();
ReflectiveInjector_ 類的方法
ReflectiveInjector_ 類中的方法較多,我們只分析其中比較重要的方法,首先先根據方法的實現的功能進行分類:
用于創建ReflectiveInjector注入器
// 基于Provider列表并創建子注入器 resolveAndCreateChild(providers: Provider[]): ReflectiveInjector { const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers); return this.createChildFromResolved(ResolvedReflectiveProviders); } // 基于已解析的ResolvedReflectiveProvider列表,創建子注入器 createChildFromResolved(providers: ResolvedReflectiveProvider[]): ReflectiveInjector { const inj = new ReflectiveInjector_(providers); inj._parent = this; return inj; }
用于獲取對象
// 獲取當前注入器的父級注入器 get parent(): Injector|null { return this._parent; } // 獲取token對應的依賴對象 get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any { return this._getByKey(ReflectiveKey.get(token), null, notFoundValue); } // 根據ReflectiveKey及visibility可見性,獲取對應的依賴對象 private _getByKey(key: ReflectiveKey, visibility: Self|SkipSelf|null, notFoundValue: any): any { // const INJECTOR_KEY = ReflectiveKey.get(Injector); if (key === INJECTOR_KEY) { return this; } // 判斷該依賴對象是否使用@Self裝飾器定義,表示從本級注入器獲取依賴對象 if (visibility instanceof Self) { return this._getByKeySelf(key, notFoundValue); } else { // 使用默認的方式獲取依賴對象 return this._getByKeyDefault(key, notFoundValue, visibility); } } // 從本級注入器獲取依賴對象 _getByKeySelf(key: ReflectiveKey, notFoundValue: any): any { const obj = this._getObjByKeyId(key.id); return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue); } // 使用默認的方式獲取依賴對象 _getByKeyDefault(key: ReflectiveKey, notFoundValue: any, visibility: Self|SkipSelf|null): any { let inj: Injector|null; // 判斷該依賴對象是否使用@SkipSelf裝飾器定義,表示不從本級注入器獲取依賴對象 if (visibility instanceof SkipSelf) { inj = this._parent; } else { inj = this; } // 從本級注入器獲取依賴對象,若本級獲取不到,則從父級注入器中查找 while (inj instanceof ReflectiveInjector_) { const inj_ = <ReflectiveInjector_>inj; const obj = inj_._getObjByKeyId(key.id); if (obj !== UNDEFINED) return obj; inj = inj_._parent; } if (inj !== null) { return inj.get(key.token, notFoundValue); } else { return this._throwOrNull(key, notFoundValue); } } // 獲取keyId對應的對象,如依賴對象未創建,則調用_new()方法創建一個,然后保存到 // this.objs對象列表中 private _getObjByKeyId(keyId: number): any { for (let i = 0; i < this.keyIds.length; i++) { if (this.keyIds[i] === keyId) { // const UNDEFINED = new Object(); if (this.objs[i] === UNDEFINED) { this.objs[i] = this._new(this._providers[i]); } return this.objs[i]; } } return UNDEFINED; }
用于創建對象
// 創建依賴對象 _new(provider: ResolvedReflectiveProvider): any { // 判斷是否存在循環依賴 if (this._constructionCounter++ > this._getMaxNumberOfObjects()) { throw cyclicDependencyError(this, provider.key); } return this._instantiateProvider(provider); } // 獲取最大的對象個數 private _getMaxNumberOfObjects(): number { return this.objs.length; } // 根據已解析的provider創建依賴對象。若是multi provider則,循環創建multi provider對象。 private _instantiateProvider(provider: ResolvedReflectiveProvider): any { if (provider.multiProvider) { const res = new Array(provider.resolvedFactories.length); for (let i = 0; i < provider.resolvedFactories.length; ++i) { res[i] = this._instantiate(provider, provider.resolvedFactories[i]); } return res; } else { return this._instantiate(provider, provider.resolvedFactories[0]); } } // 根據已解析的provider和已解析的工廠創建依賴對象 private _instantiate( provider: ResolvedReflectiveProvider, ResolvedReflectiveFactory: ResolvedReflectiveFactory): any { // 獲取對象工廠函數 const factory = ResolvedReflectiveFactory.factory; // 獲取工廠函數所依賴的對象列表 let deps: any[]; try { deps = ResolvedReflectiveFactory.dependencies .map(dep => this._getByReflectiveDependency(dep)); } catch (e) { if (e.addKey) { e.addKey(this, provider.key); } throw e; } // 調用對象工廠函數創建依賴對象 let obj: any; try { obj = factory(...deps); } catch (e) { throw instantiationError(this, e, e.stack, provider.key); } return obj; }
用于獲取工廠函數依賴對象
// 若通過@Optional裝飾器定義該依賴對象,表示該依賴對象是可選的,當獲取不到時返回null。 private _getByReflectiveDependency(dep: ReflectiveDependency): any { return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND); }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。