angular2+ 利用FactoryProvider和APP_INITIALIZER初始化项目配置

前言

本章内容需要对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 的方式声明,通过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,而是对应项目模式的配置

猜你喜欢

转载自blog.csdn.net/luo1055120207/article/details/76019759