@Inject与InjectionToken的使用

DI依赖注入是一种编码模式,构造函数中的参数通过注入器获取不需要自己创建。@Inject是参数修饰符,表示该参数是通过注入的方式获取。依赖的内容可以是类,也可以是InjectionToken,通过@Inject注入的方法使用步骤如下:

1、如果在一个自己写的类注入另一个类

可以通过ReflectiveInjector.resolveAndCreate形式先创建,再通过get方法获取实例。

2、如果在组件中或者服务中使用

(1)先在component或者模块中先用provider注入一次,providers:[{provide:类名,useFactory等}]

(2)在construtor中通过@Inject注入实例

(3)如果注入的是interface或者字符串等则需要先生成InjectionToken.

具体示例如下:

 

通过一段代码表示依赖注入与@Inject的使用有A类,B类,B类依赖类A:

class A{
  name:string;
  age:Number;
  constructor(n:string, a:number){
    this.name = n;
    this.age = a;
  }
}

/**
 * 通过依赖注入
 */
class B{
  a;
  constructor(
    @Inject(A) a:A // 通过依赖注入
  ){
    this.a = a;
  }
}

const injector = ReflectiveInjector.resolveAndCreate([
  {provide:A,useFactory:()=>{
    return new A('a',34)
  }},
  Aa
]);

const b1 = new B(injector.get(A)); // 通过injector注入
const a1 = new A(new A('dd',23)); // 通过正常的方式注入
const a2 = injector.get(A); //通过injector获取
const a3 = injector.get(A);
console.log(a2==a3); // injector.get如果无会创建,如果有直接返回

在使用@Inject(Token) value:Token之前,需要通过provider注入值。一般我们在根模块中进行注入,而后在各个类中通过@Inject进行注入。

比如在模块中或者组件装饰器中使用[{provide:Aa,useFactory:()=>{return xxx}}]进行默认的初始化

InjectionToken(来自angular中文官网):

并非所有的依赖都是类。 有时候你会希望注入字符串、函数或对象。

应用通常会用大量的小型参数来定义配置对象,比如应用的标题或 Web API 端点的地址。 这些配置对象不一定总是类的实例。 它们还可能是对象字面量,如下例所示。

export const HERO_DI_CONFIG: AppConfig = {
  apiEndpoint: 'api.heroes.com',
  title: 'Dependency Injection'
};

TypeScript 接口不是有效的令牌

HERO_DI_CONFIG 常量满足 AppConfig 接口的要求。 不幸的是,你不能用 TypeScript 的接口作为令牌。 在 TypeScript 中,接口是一个设计期的概念,无法用作 DI 框架在运行期所需的令牌。

// FAIL! Can't use interface as provider token
[{ provide: AppConfig, useValue: HERO_DI_CONFIG })]

为非类依赖选择提供商令牌的解决方案是定义并使用 InjectionToken 对象。 下面的例子展示了如何定义那样一个令牌。

import { InjectionToken } from '@angular/core';

export const APP_CONFIG = new InjectionToken<AppConfig>('app.config');

//工厂

providers: [{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }]
//注入

constructor(@Inject(APP_CONFIG) config: AppConfig) {
  this.title = config.title;
}

InjectionToken的用法

class InjectionToken<T> {
  constructor(_desc: string, options?: { providedIn?: Type<any> | "root"; factory: () => T; })
  ngInjectableDef: never | undefined
  protected _desc: string
  toString(): string
}

/*使用案例*/
const BASE_URL = new InjectionToken<string>('BaseUrl');
const injector =
    Injector.create({providers: [{provide: BASE_URL, useValue: 'http://localhost'}]});
const url = injector.get(BASE_URL);
// here `url` is inferred to be `string` because `BASE_URL` is `InjectionToken<string>`.
expect(url).toBe('http://localhost');

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值