亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

詳解Angular 4.x Injector

發布時間:2020-08-19 17:33:56 來源:腳本之家 閱讀:154 作者:semlinker 欄目:web開發

在介紹 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 抽象類子類有:

  1. _NullInjector
  2. ReflectiveInjector

下面我們來依次介紹它們:

_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() 靜態方法外,還含有以下靜態方法:

  1. resolve() - 解析 Provider 列表為 ResolvedReflectiveProvider 列表
  2. fromResolvedProviders() - 基于 ResolvedReflectiveProvider 列表創建 ReflectiveInjector 對象

接下來我們來分析上述的靜態方法:

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() 解析圖示

詳解Angular 4.x Injector 

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_ 類中的方法較多,我們只分析其中比較重要的方法,首先先根據方法的實現的功能進行分類:

  1. 用于創建ReflectiveInjector注入器
  2. 用于獲取對象
  3. 用于創建對象
  4. 用于獲取工廠函數依賴對象

用于創建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);
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阿克苏市| 湟源县| 西城区| 元阳县| 阿瓦提县| 古蔺县| 奉新县| 竹山县| 浠水县| 余姚市| 噶尔县| 海门市| 林周县| 淄博市| 泸水县| 梁山县| 甘泉县| 扎赉特旗| 揭东县| 乌什县| 山阴县| 罗田县| 同心县| 宁武县| 武平县| 聊城市| 海丰县| 原阳县| 浦县| 鹤壁市| 浮梁县| 吴桥县| 怀仁县| 绥江县| 南澳县| 慈溪市| 唐海县| 罗定市| 阿鲁科尔沁旗| 通化市| 万盛区|