【发布时间】:2021-03-10 02:24:58
【问题描述】:
我想在后端服务器关闭时自动提供“存根”服务。目前我通过手动更改配置设置“isRunning”来做到这一点。但出于多种原因,我希望在不编辑代码或配置文件的情况下完成此检查。
let isRunning: boolean = true;
...
providers: [
{
provide: MyService,
useClass: isRunning ? MyService : MyServiceStub
},
...
],
我尝试使用 APP_INITIALIZER 注入令牌,以便在加载应用程序之前“ping”服务器并在选择提供程序时测试结果。 (此代码既是on Github,也可以查看in this Stackblitz。
function IsRunning(){
return AppInitService.isWebServerRunning();
}
...
providers: [
{
provide: MyService,
useClass: IsRunning() ? MyService : MyServiceStub
}
],
但我遇到的问题是“isRunning()”在框架已经选择并将 MyService 添加到依赖注入器之后返回其结果。因此,即使上面的“isRunning()”返回 false,它仍然选择 MyService 而不是 MyServiceStub。
如果您运行 Stackblitz,您可以从控制台日志中看到这是真的。 MyService 构造函数中的 console.log 语句在 IsRunning() 返回之前输出。
还有其他方法可以做到这一点。我是否可以在 IsRunning() 函数中包含手动注入提供程序而不是依赖于 @NgModule 中的提供程序数组的代码。
APP_INITIALIZER 令牌及其提供服务的工厂在 AppInitModule 中实现:
export function pingFactory(appInitService: AppInitService) {
return () => appInitService.pingServer();
}
@NgModule({
imports: [HttpClientModule],
providers: [
AppInitService,
{ provide: APP_INITIALIZER, useFactory: pingFactory, deps: [AppInitService], multi: true },
],
})
export class AppInitModule {}
这里是 AppInitService 的代码:
@Injectable({providedIn: 'root'})
export class AppInitService {
constructor(private httpClient: HttpClient) {}
static isRunning: boolean | null = null;
static async isWebServerRunning() {
logMsg("isWebServerRunning Enter");
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
// check every 50 milliseconds for change in "isRunning" status
while (AppInitService.isRunning === null) {
logMsg("isWebServerRunning in delay loop");
await delay(50);
}
let isrunning = AppInitService.isRunning;
logMsg("isWebServerRunning Exit -isRunnning = " + String(isrunning));
return isrunning;
}
pingServer(): Promise<any> {
logMsg("pingServer. Enter");
const promise = this.httpClient
.get(server)
.toPromise()
.then((settings) => {
logMsg("pingServer Got server response");
AppInitService.isRunning = true;
return true;
})
.catch((err) => {
logMsg("pingServer No server Response");
AppInitService.isRunning = false;
err;
});
return promise;
}
}
【问题讨论】:
标签: angular typescript dependency-injection