几次遇到这个问题后,我设计了一个很好的方法来克服它,方法是在 AngularInjector
服务中使用 getter,而不是直接在构造函数中注入服务。这允许在被引用之前构建服务时间。我的示例仅使用服务,但同样的事情可以应用于使用服务的组件,只需将 getter 放在组件中,而不是BService
在示例中。
我所做的是使用 getter 将服务注入到使用Injector
类的类属性中,如果之前尚未设置类属性,那么服务只会注入一次(第一次调用 getter 时)。这使得服务的使用方式与在构造函数中注入的方式基本相同,但不会出现循环引用错误。只需使用吸气剂this.aService
。他们唯一一次不起作用的是,如果您尝试AService
在 的构造函数中使用Bservice
,那么您将遇到相同的循环引用问题,因为Aservice
还没有准备好。通过使用 getter,您可以推迟注入服务,直到您需要它。
有一些论点认为,AService
取决于BService
和BService
取决于AService
,是不好的形式,但每条规则都有例外,每种情况都不同,所以在我看来,这是处理这个问题的一种简单有效的方法。
// a.service.ts
import { Injectable } from '@angular/core';
import { BService } from './b.service';
@Injectable({
providedIn: 'root'
})
export class AService {
constructor(
private bService: BService,
) { }
public foo() {
console.log('foo function in AService!');
this.bService.bar();
}
}
// b.service.ts
import { Injectable, Injector } from '@angular/core';
import { AService } from './a.service';
@Injectable({
providedIn: 'root'
})
export class BService {
// Use the getter 'aService' to use 'AService', not this variable.
private _aService: AService;
constructor(
private _injector: Injector,
) { }
// Use this getter to use 'AService' NOT the _aService variable.
get aService(): AService {
if (!this._aService) {
this._aService = this._injector.get(AService);
}
return this._aService;
}
public bar() {
console.log('bar function in BService!');
this.aService.foo();
}
}