问题描述
我在将依赖项注入拦截器时遇到问题。我想将 TranslateService 注入 HttpErrorInterceptor,但出现循环依赖错误。当我删除 TranslateService 注入时,一切正常。
我在 app.module.ts 中声明了拦截器。 我的应用模块如下所示:
@NgModule({
declarations: [
AppComponent
],imports: [
browserModule,browserAnimationsModule,CoreModule,HttpClientModule,TranslateModule.forRoot({
loader: {
provide: TranslateLoader,useFactory: HttpLoaderFactory,deps: [HttpClient],},defaultLanguage: 'pl-pl'
}),AppRoutingModule,RouterModule,FormsModule,ReactiveFormsModule,ToastrModule.forRoot()
],providers: [
{
provide: HTTP_INTERCEPTORS,useClass: JwtInterceptor,multi: true
},{
provide: HTTP_INTERCEPTORS,useClass: HttpErrorInterceptor,multi: true,deps: [TranslateService,ToastrService]
}
],bootstrap: [AppComponent]
})
export class AppModule { }
在 AppModule 中,我导入了 CoreModule,其中有一个包含拦截器的文件夹,我的 CoreModule 如下所示:
@NgModule({
declarations: [],imports: [
CommonModule
],providers: [
CookieService,NoAuthGuard,AuthGuard
]
})
export class CoreModule { }
@NgModule({
declarations: [LoginComponent,AuthComponent,ForgotPasswordComponent],imports: [
CommonModule,AuthRoutingModule,SharedModule
],providers: [
AuthService
]
})
export class AuthModule { }
在 Authmodule 中,我导入了 SharedModule,其中我导出了 TranslateModule。 而 SharedModule 看起来像这样:
@NgModule({
declarations: [],ReactiveFormsModule
],exports: [
TranslateModule,ReactiveFormsModule
]
})
export class SharedModule { }
我的假设是我已经将 CoreModule 导入到 AppModule 中,在那里我保留了拦截器、守卫和 SharedModule,它对所有功能模块进行了即兴发挥,我想保留例如那里有通用组件。
Błąd,jaki dostaję 到:
core.js:6162 ERROR Error: NG0200: Circular dependency in DI detected for InjectionToken HTTP_INTERCEPTORS. Find more at https://angular.io/errors/NG0200
at throwCyclicDependencyError (core.js:216)
at R3Injector.hydrate (core.js:11381)
at R3Injector.get (core.js:11205)
at HttpInterceptingHandler.handle (http.js:1978)
at MergeMapSubscriber.project (http.js:1114)
at MergeMapSubscriber._tryNext (mergeMap.js:44)
at MergeMapSubscriber._next (mergeMap.js:34)
at MergeMapSubscriber.next (Subscriber.js:49)
at Observable._subscribe (subscribetoArray.js:3)
at Observable._trySubscribe (Observable.js:42)
请帮忙。
解决方法
您遇到的问题是,对于 TranslateModule
的初始化,您依赖于 HttpClient
,这意味着需要先初始化 HttpClientModule
。这会导致您的 HttpErrorInterceptor
初始化,因为拦截器是使用 HttpClientModule
初始化进行初始化的。这会导致循环依赖,因为您的拦截器需要 TranslateService
。您可以通过在 HttpErrorInterceptor
中注入 Injector 来解决此问题,然后在需要时直接从注入器按需请求 TranslateService
。这样可以防止对初始初始化的循环依赖。
由于您没有为拦截器提供代码,这里提供了一个使用这种方法的拦截器示例。
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
constructor(private readonly injector: Injector) {}
public intercept(req: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
try {
const translateService = this.injector.get(TranslateService)
// log using translate service
} catch {
// log without translation translation service is not yet available
}
}
}
您仍然需要处理获取翻译服务失败的情况,因为您可能会在加载翻译时出错。