查看新版教程,請訪問前端修仙之路前端
在介紹 Angular Injector (注入器) 以前,咱們先要了解 Dependency Injection,即依賴注入的概念。typescript
在軟件工程中,依賴注入是種實現控制反轉用於解決依賴性設計模式。一個依賴關係指的是可被利用的一種對象(即服務提供端) 。依賴注入是將所依賴的傳遞給將使用的從屬對象(即客戶端)。該服務是將會變成客戶端的狀態的一部分。 傳遞服務給客戶端,而非容許客戶端來創建或尋找服務,是本設計模式的基本要求。 —— 維基百科編程
依賴注入容許程序設計聽從依賴倒置原則 (簡單的說就是要求對抽象進行編程,不要對實現進行編程,這樣就下降了客戶端與實現模塊間的耦合) 調用者只需知道服務的接口,具體服務的查找和建立由注入器 (Injector) 負責處理並提供給調用者,這樣就分離了服務和調用者的依賴,符合低耦合的程序設計原則。segmentfault
從上述的內容可知,依賴注入中包含三種角色:調用者、服務和注入器 (Injector)。如今咱們開始介紹 Injector,在 Angular 中 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 抽象類子類有:api
下面咱們來依次介紹它們:數組
_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 表示一個依賴注入容器,用於實例化對象和解析依賴。緩存
@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()
靜態方法外,還含有如下靜態方法:angular2
接下來咱們來分析上述的靜態方法:
static resolveAndCreate(providers: Provider[], parent?: Injector): ReflectiveInjector {
const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
}
複製代碼
從上面代碼中,咱們能夠看出 resolveAndCreate()
方法內部是經過調用 ReflectiveInjector.resolve()
方法和 ReflectiveInjector.fromResolvedProviders()
方法來建立 ReflectiveInjector 對象。
該方法用於把 Provider 數組解析爲 ResolvedReflectiveProvider 數組。
static resolve(providers: Provider[]): ResolvedReflectiveProvider[] {
return resolveReflectiveProviders(providers);
}
複製代碼
@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");
複製代碼
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;
}
複製代碼
export interface ResolvedReflectiveProvider {
// 惟一的對象用來從ReflectiveInjector中獲取對象
key: ReflectiveKey;
// 工廠函數用於建立key相關的依賴對象
resolvedFactories: ResolvedReflectiveFactory[];
// 標識當前的provider是否爲multi-provider
multiProvider: boolean;
}
複製代碼
export class ResolvedReflectiveFactory {
constructor( public factory: Function, public dependencies: 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 對象中包含兩個屬性:系統範圍內惟一的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()); // 步驟四
}
複製代碼
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 {}
複製代碼
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);
}
複製代碼
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;
}
複製代碼
// resolvedProviderMap的values,建立ResolvedReflectiveProvider[]
Array.from(resolvedProviderMap.values());
/** * 基於一個相似數組或可迭代對象建立一個新的數組實例 * * arrayLike:轉換成真實數組的類數組對象或可遍歷對象。 * mapFn(可選):若是指定了該參數,則最後生成的數組會通過該函數的加工處理後再返回。 * thisArg(可選):執行mapFn函數時this的值。 */
Array.from(arrayLike[, mapFn[, thisArg]])
複製代碼
該方法用於基於已解析的 providers 建立注入器。
static fromResolvedProviders(providers: ResolvedReflectiveProvider[], parent?: Injector):
ReflectiveInjector {
return new ReflectiveInjector_(providers, parent);
}
複製代碼
@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_
類。
// 構造次數
_constructionCounter: number = 0;
// ResolvedReflectiveProvider列表
public _providers: ResolvedReflectiveProvider[];
// 父級注入器
public _parent: Injector|null;
// ReflectiveKey id列表
keyIds: number[];
// 依賴對象列表
objs: any[];
複製代碼
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_ 類中的方法較多,咱們只分析其中比較重要的方法,首先先根據方法的實現的功能進行分類:
// 基於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);
}
複製代碼
其實 Angular DI 最核心的內容是,如何建立依賴對象?在 Angular 中咱們經過使用工廠函數,來建立依賴對象。工廠函數的輸入參數是依賴對象列表,輸出結果是對應的依賴對象。所以接下來咱們將着重介紹如何建立工廠函數和如何建立依賴對象?但在開始介紹以前,咱們還得先介紹一下 Angular Metadata 的相關內容。
在 Angular 中 Metadata 主要分爲如下幾種類型:
接下來咱們來看一下具體示例:
友情提示:其中 design:paramtypes 和 parameters metadata 類型主要用於實現依賴注入
Angular 使用第三方庫 core-js
提供的 Reflect API ,來實現對 Metadata 信息的存儲與讀取。
咱們以類裝飾器爲例,如 @Component()
、@NgModule()
:
// angular2/packages/core/src/util/decorators.ts
export function makeDecorator(
name: string,
props: {[name: string]: any},
parentClass?: any,
chainFn?: (fn: Function) => void): (...args: any[]) => (cls: any) => any {
//...
const TypeDecorator: TypeDecorator = <TypeDecorator>function TypeDecorator(cls:
Type<any>) {
const annotations = Reflect.getOwnMetadata('annotations', cls) || [];
annotations.push(annotationInstance);
// 保存annotations metadata信息
Reflect.defineMetadata('annotations', annotations, cls);
return cls;
};
}
複製代碼
Reflect.defineMetadata()
方法用來保存定義的 Metadata 信息,相應的 Metadata 信息是保存在 window['__core-js_shared__']
對象的 metadata 屬性中。感興趣的話,你們能夠直接在控制檯,輸入 window['__core-js_shared__']
查看該對象的內部信息。介紹完 Metadata 信息的保存,咱們來了解一下如何獲取 Metadata 信息。
Angular 中經過 ReflectorReader
抽象類,定義了讀取 Metadata 信息相關的抽象方法:
export abstract class ReflectorReader {
abstract parameters(typeOrFunc: /*Type*/ any): any[][];
abstract annotations(typeOrFunc: /*Type*/ any): any[];
abstract propMetadata(typeOrFunc: /*Type*/ any): {[key: string]: any[]};
abstract importUri(typeOrFunc: /*Type*/ any): string|null;
abstract resourceUri(typeOrFunc: /*Type*/ any): string;
abstract resolveIdentifier(name: string, moduleUrl: string, members: string[],
runtime: any): any;
abstract resolveEnum(identifier: any, name: string): any;
}
複製代碼
上述抽象方法的具體實現類是 - Reflector
類:
// angular2/packages/core/src/reflection/reflector.ts
export class Reflector extends ReflectorReader {
constructor(public reflectionCapabilities: PlatformReflectionCapabilities) {
super();
}
//...
factory(type: Type<any>): Function { return this.reflectionCapabilities.factory(type); }
parameters(typeOrFunc: Type<any>): any[][] {
return this.reflectionCapabilities.parameters(typeOrFunc);
}
annotations(typeOrFunc: Type<any>): any[] {
return this.reflectionCapabilities.annotations(typeOrFunc);
}
propMetadata(typeOrFunc: Type<any>): {[key: string]: any[]} {
return this.reflectionCapabilities.propMetadata(typeOrFunc);
}
}
複製代碼
介紹完 Angular Metadata 的相關知識,咱們來開始介紹如何建立依賴對象。
// 解析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);
}
複製代碼
// { provide: ApiService, useClass: ApiService }
const useClass = resolveForwardRef(provider.useClass);
factoryFn = reflector.factory(useClass);
resolvedDeps = _dependenciesFor(useClass);
複製代碼
// 獲取經過forwardRef()方法定義的類
const useClass = resolveForwardRef(provider.useClass);
factoryFn = reflector.factory(useClass);
// reflector.factory() 方法
factory<T>(t: Type<T>): (args: any[]) => T {
return (...args: any[]) => new t(...args);
}
複製代碼
// 解析類中的依賴對象
function _dependenciesFor(typeOrFunc: any): ReflectiveDependency[] {
// 獲取design:paramtypes和paramters保存的metadata信息
const params = reflector.parameters(typeOrFunc);
if (!params) return [];
if (params.some(p => p == null)) {
throw noAnnotationError(typeOrFunc, params);
}
return params.map(p => _extractToken(typeOrFunc, p, params));
}
// 建立ReflectiveDependency對象
function _extractToken(typeOrFunc: any, metadata: any[] | any, params: any[][]): ReflectiveDependency {
let token: any = null;
let optional = false;
if (!Array.isArray(metadata)) {
// Inject: InjectDecorator = makeParamDecorator('Inject', [['token',
// undefined]]);
if (metadata instanceof Inject) {
return _createDependency(metadata['token'], optional, null);
} else {
return _createDependency(metadata, optional, null);
}
}
let visibility: Self|SkipSelf|null = null;
// 遍歷metadata數組,設置token、optional(可選的)、visibility(可見性)的值
for (let i = 0; i < metadata.length; ++i) {
const paramMetadata = metadata[i];
if (paramMetadata instanceof Type) {
token = paramMetadata;
} else if (paramMetadata instanceof Inject) {
token = paramMetadata['token'];
} else if (paramMetadata instanceof Optional) {
optional = true;
} else if (paramMetadata instanceof Self ||
paramMetadata instanceof SkipSelf) {
visibility = paramMetadata;
} else if (paramMetadata instanceof InjectionToken) {
token = paramMetadata;
}
}
// 獲取經過forwardRef()方法定義的類
token = resolveForwardRef(token);
if (token != null) {
return _createDependency(token, optional, visibility);
} else {
throw noAnnotationError(typeOrFunc, params);
}
}
// 建立ReflectiveDependency對象
function _createDependency( token: any, // 依賴對象關聯的token optional: boolean, // 是不是可選的 visibility: Self | SkipSelf | null): ReflectiveDependency {
return new ReflectiveDependency(
ReflectiveKey.get(token),
optional,
visibility);
}
複製代碼
// { provide: 'ApiServiceAlias', useExisting: ApiService }
factoryFn = (aliasInstance: any) => aliasInstance;
resolvedDeps = [ReflectiveDependency
.fromKey(ReflectiveKey.get(provider.useExisting))];
複製代碼
factoryFn = (aliasInstance: any) => aliasInstance;
複製代碼
// { provide: 'ApiServiceAlias', useExisting: ApiService }
resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
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);
}
}
複製代碼
// { provide: APP_INITIALIZER, useFactory: configFactory, deps: [AppConfig],
// multi: true }
factoryFn = provider.useFactory;
resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
複製代碼
factoryFn = provider.useFactory;
複製代碼
resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
// 構造ReflectiveDependency[]列表
export function constructDependencies( typeOrFunc: any, dependencies?: any[]): ReflectiveDependency[] {
if (!dependencies) {
return _dependenciesFor(typeOrFunc);
} else {
const params: any[][] = dependencies.map(t => [t]);
return dependencies.map(t => _extractToken(typeOrFunc, t, params));
}
}
複製代碼
// { provide: 'API_URL', useValue: 'http://my.api.com/v1' }
factoryFn = () => provider.useValue;
resolvedDeps = _EMPTY_LIST; // const _EMPTY_LIST: any[] = [];
複製代碼
factoryFn = () => provider.useValue;
複製代碼
resolvedDeps = _EMPTY_LIST; // const _EMPTY_LIST: any[] = [];
複製代碼
如今 Angular Injector 的相關知識,已經介紹完了。因爲涉及過多的源碼,沒介紹清楚的地方,請見諒。
詳細的內容能夠參考 - Angular 2 DI - IoC & DI - 1
Angular 中注入器是有層級結構的,即建立完注入器,咱們能夠基於它建立它的子注入器。
當調用注入器 get()
方法,獲取 token 對應的對象時,默認的查找方式是,優先從本級注入級獲取,若是未找到,則往上一級查找,直到根級注入器。若未找到對應的依賴對象,默認會拋出異常。
class ParentProvider {}
class ChildProvider {}
var parent = ReflectiveInjector.resolveAndCreate([ParentProvider]);
var child = parent.resolveAndCreateChild([ChildProvider]);
expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
複製代碼
經過分析源碼,咱們也發現若是兩個服務提供商 (Provider) 使用同一個 Token,卻沒有聲明爲 multi provider,那麼後面的會把前面的覆蓋掉。此外須要注意的是,multi provider 不能與普通的 provider 混用。