我正在使用 Angular 10,并且有一些服务和一个拦截器导致:
ERROR Error: Uncaught (in promise): Error: Cannot instantiate cyclic dependency! InjectionToken HTTP_INTERCEPTORS Error: Cannot instantiate cyclic dependency! InjectionToken HTTP_INTERCEPTORS
app.module.ts
@NgModule({
declarations: [
AppComponent,
DashboardComponent,
],
imports: [
AuthModule, // <= A custom module
BrowserModule,
AppRoutingModule,
HttpClientModule,
],
providers: [
{provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true},
],
bootstrap: [AppComponent]
})
export class AppModule {
}
拦截器
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(
private responseHandler: HttpResponseHandlerService
) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
catchError((err: HttpErrorResponse, source) =>
this.responseHandler.onCatch(err, source) // Catching all the errors here.
)
);
}
}
HttpResponseHandlerService
@Injectable({
providedIn: 'root',
})
export class HttpResponseHandlerService {
constructor(
// This is causing the error!
private authService: AuthService
) {
}
public onCatch(response: HttpErrorResponse, source: Observable<any>): Observable<any> {
return throwError(response);
}
}
验证模块
@NgModule({
declarations: [
LoginComponent
],
imports: [
SharedModule, // <= A shared module
AuthRoutingModule
],
providers: [
AuthService
]
})
export class AuthModule {
}
验证服务
@Injectable()
export class AuthService extends HttpService {
constructor(
// Maybe this is causing the cyclic dependency ?
http: HttpClient
) {
super(http);
}
login(username: string, password: string) {
}
}
共享模块
@NgModule({
declarations: [],
imports: [
CommonModule,
],
exports: [
FormsModule,
ReactiveFormsModule,
],
providers: [
HttpService // <= A custom service to handle HTTP requests
]
})
export class SharedModule {
}
Http服务
@Injectable()
export class HttpService {
constructor(
private http: HttpClient
) {
}
get<T>(options: any): Observable<T> {
}
}
我已经尝试了所有方法,但无法解决这个问题。我不明白错误的根源。
我的目标是正确解决循环依赖问题。
最佳答案
我猜测 HttpClient 会注入(inject) HTTP 拦截器。所以这一行:
{provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true},
可能使得 Angular 需要先创建一个 ErrorInterceptor 实例,然后才能创建 HttpClient。
但是ErrorInterceptor注入(inject)了HttpResponseHandlerService,HttpResponseHandlerService又注入(inject)了AuthService,AuthService又注入(inject)了HttpClient。所以 Angular 就像:
new AuthService(
new HttpClient([new ErrorInterceptor(
new HttpResponseHandlerService(
new AuthService(
... wait a minute.
解决此问题的最佳方法在一定程度上取决于这些不同服务之间依赖关系的性质。
希望如果您查看 HttpResponseHandlerService
计划使用 AuthService
做什么,您会发现您正在调用一个方法实际上并不需要HttpClient
。如果是这种情况,也许您可以将该方法重构为一个单独的服务,该服务可以安全地注入(inject)到 HttpResponseHandlerService
中。
如果情况并非如此,您可能需要考虑其他模式,例如让 AuthService
从工厂或服务定位器按需获取 HttpClient,而不是直接注入(inject)它。
关于angular - 无法在拦截器使用的服务内实例化循环依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64016059/