详解Angular 4.x Injector

前端之家收集整理的这篇文章主要介绍了详解Angular 4.x Injector前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在介绍 Angular Injector (注入器) 之前,我们先要了解 Dependency Injection,即依赖注入的概念。

依赖注入允许程序设计遵从依赖倒置原则 (简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户端与实现模块间的耦合) 调用者只需知道服务的接口,具体服务的查找和创建由注入器 (Injector) 负责处理并提供给调用者,这样就分离了服务和调用者的依赖,符合低耦合的程序设计原则。

从上述的内容可知,依赖注入中包含三种角色:调用者、服务和注入器 (Injector)。现在我们开始介绍 Injector,在 Angular 中 Injector (注入器) 用来管理服务对象的创建和获取。接下来我们先来看一下 Injector 抽象类:

Injector 抽象类

/**

  • 用于根据给定的Token从注入器中获取相应的对象。
  • 如果没有找到相应的对象,将返回notFoundValue设置的值。若notFoundValue的值与
  • _THROW_IF_NOT_FOUND相等,则会抛出异常。
    */
    abstract get(token: Type|InjectionToken,notFoundValue?: T): T;
    }

const _THROW_IF_NOT_FOUND = new Object();

Injector 抽象类中定义了一个 get() 抽象方法,该方法用于根据给定的 Token 从注入器中获取相应的对象,每个Injector 抽象类的子类都必须实现该方法。在 Angular 中常见的 Injector 抽象类子类有:

  1. _NullInjector
  2. ReflectiveInjector

下面我们来依次介绍它们:

_NullInjector 类

_NullInjector 类的实例用于表示空的注入器。

ReflectiveInjector 抽象类

ReflectiveInjector 表示一个依赖注入容器,用于实例化对象和解析依赖。

ReflectiveInjector 使用示例

@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()

从上面代码中,我们可以看出 resolveAndCreate() 方法内部是通过调用 ReflectiveInjector.resolve() 方法ReflectiveInjector.fromResolvedProviders() 方法来创建 ReflectiveInjector 对象。

resolve()

方法用于把 Provider 数组解析为 ResolvedReflectiveProvider 数组。

resolve() 使用示例

@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 类型

// ApiService
export interface TypeProvider extends Type {}

// { provide: ApiService,useClass: ApiService }
export interface ClassProvider {
// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
provide: any;
useClass: Type;
// 用于标识是否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 接口

获取对象 key: ReflectiveKey; // 工厂函数用于创建key相关的依赖对象 resolvedFactories: ResolvedReflectiveFactory[]; // 标识当前的provider是否为multi-provider multiProvider: boolean; }

ResolvedReflectiveFactory 类

ReflectiveDependency 类

static fromKey(key: ReflectiveKey): ReflectiveDependency {
return new ReflectiveDependency(key,false,null);
}
}

ReflectiveKey 类

ReflectiveKey 对象中包含两个属性:系统范围内唯一的id 和 token。系统范围内唯一的id,允许注入器以更高效的方式存储已创建的对象。另外我们不能手动的创建 ReflectiveKey,当 ReflectiveInjector 对象解析 providers 的时候会自动创建 ReflectiveKey 对象。

// 返回序列化的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() 方法的输入参数和返回类型,我们来看一下该方法内部的具体实现:

步骤一 —— 规范化Provider

// 规范化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

// 解析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,// 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

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[]

/**

  • 基于一个类似数组或可迭代对象创建一个新的数组实例
  • arrayLike:转换成真实数组的类数组对象或可遍历对象。
  • mapFn(可选):如果指定了该参数,则最后生成的数组会经过该函数的加工处理后再返回。
  • thisArg(可选):执行mapFn函数时this的值。
    */
    Array.from(arrayLike[,mapFn[,thisArg]])

fromResolvedProviders()

方法用于基于已解析的 providers 创建注入器。

fromResolvedProviders() 使用示例

@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_ 构造函数

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注入器

// 基于已解析的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
= 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;
}

用于创建对象

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;
}

用于获取工厂函数依赖对象

获取不到时返回null。 private _getByReflectiveDependency(dep: ReflectiveDependency): any { return this._getByKey(dep.key,dep.visibility,dep.optional ? null : THROW_IF_NOT_FOUND); }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

猜你在找的JavaScript相关文章