详解Angular 4.x Injector
在介绍 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
- 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()
静态方法外,还含有以下静态方法:
- resolve() - 解析 provider 列表为 resolvedreflectiveprovider 列表
- 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() 解析图示
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注入器
- 用于获取对象
- 用于创建对象
- 用于获取工厂函数依赖对象
用于创建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); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Python基于递归算法求最小公倍数和最大公约数示例
下一篇: AngularJS 霸道的过滤器小结