Angular入门之依赖注入

时间:2021-10-30 12:04:02

是什么

依赖注入(dependency injection,DI)是这样一个系统,它让程序中的某部分可以访问其他部分,而且我们可以配置它们的访问方式。
简单来说,就是new好了依赖的对象注入进去,而不是在类中显式的new一个依赖的对象。依赖注入的可以是继承依赖类(即constructor参数)的任何类

基于控制反转(Ioc)的设计原则,减弱耦合性

Angular入门之依赖注入


怎么用

即如何给组件注入服务:

  1. 创建该服务的类,服务类上面这个@Injectable()装饰器

  2. 配置要注入的依赖,即提供者
    Angular 在启动过程中自动为我们创建一个应用级注入器,即隐式注入器。我们必须通过注册provider来配置注入器,这些provider为应用创建所需服务。
    或者在 NgModule 中注册provider,或者在应用组件中。使用Provider:[1]告诉Angular如何*根据指定的令牌创建对象***1的内容见下部分

    • NgModule 中的provider是被注册到根注入器。这意味着在 NgModule 中注册的provider可以被整个应用访问。
    • 在应用组件中注册的provider只在该组件及其子组件中可用。
  3. 在准备接收注入的部件上声明该依赖
    先导入该服务(import),然后在组件的构造函数中声明它。声明有两种方式:使用Inject注解的和不使用Inject注解的
    非 Type 类型的参数只能用 @Inject(Something) 的方式注入;Type 类型的参数两种方式都可以,比如

//非Type类型
constructor(@Inject(ApiService) private apiService){ }

//Type类型
constructor(private http: Http) { } //推荐
constructor(@Inject(Http) private http) { }
constructor(@Inject(Http) private http:
Http) { }

因为 Type 类型的对象,会被 TypeScript 编译器编译。即我们通过 class 关键字声明的服务,最终都会编译成 ES5 的函数对象


显示注入器

可以写使用显式注入器的代码,但却很少这样做

  injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]);
let car = injector.get(Car);

provider配置

  1. 单例模式:服务的构造函数无参数,每次注入时返回同一个实例,1的内容:
    {provide:'令牌名',useClass:注入服务的类名}
    可简写为:注入服务的类名

  2. 工厂模式:调用构造函数时需要提供参数
    {provide: '令牌名',useFactory:函数}

  3. 值模式:当需要一个常量,而它会根据应用的其他部分甚至环境进行重定义时,这种方式非常有用
    {provide: '令牌名', useValue: 'someValue'}

  4. 别名模式
    {provide: '令牌名', useValue: '其他令牌名'}

四种接口的API如下:

export interface ClassProvider {
// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
provide: any;
useClass: Type<any>;
// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表
multi?: boolean;
}

export interface FactoryProvider {
// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
provide: any;
// 设置用于创建对象的工厂函数
useFactory: Function;
// 依赖对象列表
deps?: any[];
// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表
multi?: boolean;
}

export interface ValueProvider {
// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
provide: any;
// 设置注入的对象
useValue: any;
// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表
multi?: boolean;
}

export interface ExistingProvider {
// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
provide: any;
// 设置注入的对象
useExisting: any;
// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表
multi?: boolean;
}

推荐从设计模式看依赖注入