前言
本章内容需要对angular2的依赖注入,多注入有一定了解
1、angular2依赖注入是什么?
我简要形象的描述一下依赖注入:你现在到餐厅吃饭,你需要点一个菜,你只需要说出你想吃什么菜,然后餐厅的厨师就会帮你把这个菜做出来并端到你的面前,而你不用关心整个做菜的过程,做菜依赖哪些原材料,这就是依赖注入的生活释义
2、FactoryProvider 接口定义?
export interface FactoryProvider {
provide: any;// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
useFactory: Function;// 设置用于创建对象的工厂函数
deps?: any[]; // 依赖对象列表
multi?: boolean;// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表
}
这段话摘在semlinker大佬的依赖注入详解,简要解释一下各个参数的含义,provide就是你要依据什么信息去获取你需要的对象,相当于你要点的菜的名字;useFactory就是帮你创建对象的函数,相当于给你炒菜的厨师;deps就是创建你需要的对象所依赖的其他对象列表,相当于炒菜(宫保鸡丁)需要的佐料,原材料(比如鸡丁等);multi用于标识是否是多注入,相当于你炒菜你需要其他材料,所以你要声明 multi=true
,当然不需要依赖其他对象时可以设置 multi=false
3、FactoryProvider有何用
FactoryProvider 用于告诉 Injector (注入器),通过调用 useFactory 对应的函数,返回 Token 对应的依赖对象。
4、APP_INITIALIZER 的定义
export const APP_INITIALIZER = new InjectionToken<Array<() => void>>
('Application Initializer');
使用 InjectionToken<T> 的方式声明,通过InjectionToken函数我们发现:APP_INITIALIZER关联的对象是数组,数组内的每一个元素都是函数对象
5、APP_INITIALIZER有何用?
该 Token 用于配置系统初始化相关的 Provider
export function configFactory(config: AppConfig) {
return function () { config.load(); } //返回一个函数对象
}
@NgModule({
...,
providers: [
// 系统启动时,加载项目的配置文件,如系统登录、首页模块的ApiUrl等信息
{ provide: APP_INITIALIZER, useFactory: configFactory,
deps: [AppConfig], multi: true }
]
})
export class AppModule { }
6、利用FactoryProvider和APP_INITIALIZER能做什么?
能够初始化项目的配置,比如你调用接口时,我们为了让接口更灵活,也更容易替换,我们一般会省略接口前面的ip地址和端口号,例如这样 :const url="mes/getMech"
,这里我们省略了前面的 http://192.168.0.52:8080/
(这是我随便造的ip地址),为什么要这么设计,我解释一下:我们可能测试数据用一个数据库,发布产品时肯定用另一个数据库,你如果ip地址写死了,那么http请求获取时的每一个接口前面的ip地址和端口号都需要修改,想想就知道这是一个多么伟大的工程,然而利用FactoryProvider和APP_INITIALIZER,你能把这些配置存在一个全局的class类里面,而且这个类在项目初始化时最早执行
7、项目初始化配置具体实现?
简要分析一下代码:通过 this.http.get('assets/config/env.json')
拿到我们的项目模式并存到this.env
里面,比如:开发模式、发布模式,env.json文件配置如下:
通过项目模式获取每一种模式下的项目基本初始化配置,这里我们有三种模式下的配置:prod、dev、test,然后获取
this.env.env
里面指定的模式的配置,并存到 this.config
里面,下面我们看一下三种模式的相关配置(1)prod:
(2)dev:
(3)test:
在AppModule里面进行注入:
8、验证初始化顺序
为了验证APP_INITIALIZER是不是在项目启动时最早初始化,我们只需比较AppConfig和AppComponent两个类谁先执行,下面我们来看AppComponent的代码:
我们通过对比AppConfig类和AppComponent类中的log信息(我都用红色长方形进行了标记),就能验证我们的结果
通过log我们发现AppConfig类确实要比AppComponent类先执行,也正因为AppConfig类先执行,AppComponent使用AppConfig类进行依赖注入的时候AppConfig类的成员变量
this.config
不是undefined,而是对应项目模式的配置