发布于 1年前

Angular依赖注入注解inject()和注解@Inject

注解@Inject

Angular提供了注解@Inject来向组件或服务注入实例,例如:

@Injectable()
class AService{
  constructor(@Inject(BService) bService:BService) {
  }  
}

这等同于添加访问修饰符后去掉注解,这也是我们常用的方式,上面示例可改为:

@Injectable()
class AService{
  //去掉了注解@Inject,注意需要添加访问修饰符private/protec/public
  constructor(private bService:BService) {
  }  
}

使用@Inject()注解有个限制,它只能在构造器参数上使用。

手动依赖注入方法inject()

inject()函数是Ivy引进来的,支持使用命令式做依赖注入。相对于注解@Inject仅限在构造函数参数上使用,inject()函数使用范围有所扩大,但仍有限制。inject()函数只能在以下几处使用:

  1. 由依赖注入实例化的类构造函数,例如@Injectable或@Component。
  2. 类字段属性的初始化
  3. 在为 Provider 或 @Injectable 的 useFactory 指定的工厂函数中。
  4. 在为InjectionToken 指定的工厂函数中。

这几处都是在类实例化创建的上下文中调用inject()函数。

类的构造函数

@Injectable()
class AService
  private bService: BService;
  constructor() {
    this.bService = inject(BService);
  }  
}

类属性字段

@Injectable()
class AService
  private bService: BService = inject(BService);
  constructor() {
  }  
}

provider工厂函数

providers: [
  {provide: AService, useFactory: () => {
    const bService= inject(BService);
    return new AService(bService);
  }}
]

调用报NG0203错

在类创建上下文之外调用 inject() 函数会报错。有一个地方要注意,在创建类实例后,在类的其他方法(包括生命周期挂钩)中不允许调用 inject(), 如ngOnInit:

@Component({ ... })
export class MyComponent {
  ngOnInit() {
    // ERROR: 此处调用时已经晚了,因为MyComponent已经实例化完成
    const myService= inject(MySerivce);
  }
}

它报NG0203错误,信息类似:

core.mjs:6494 ERROR Error: NG0203: inject() must be called from an injection context
at injectInjectorOnly (core.mjs:4768:1)
at ɵɵinject (core.mjs:4778:1)
at Module.ɵɵdirectiveInject (core.mjs:14430:1)

angular版本的影响

在Angular13以及之前的版本,是不支持在@Component和@Directive中使用,Angular 14已修正以支持在组件和指令中使用.

©2020 edoou.com   京ICP备16001874号-3