首页 > 解决方案 > 当服务需要导入另一个服务时如何避免“循环依赖”错误

问题描述

我正在编写一个 Angular 前端,我想在其中收集对同一服务中后端的所有 HTTP 调用。

失败的提交就在这里只需进行一项更改即可工作),我将在下面进行总结。

所以,我有这个BackendService类:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, BehaviorSubject } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

const backendUrl = 'http://localhost:5001/api/';
const statusEndpoint = '/status';

@Injectable({
  providedIn: 'root'
})
export class BackendService {
  // exposed Subject of this service
  public status$ = new BehaviorSubject<BackendStatus>(defaultStatus);

  constructor(
    private http: HttpClient,
  ) { }

  private updateStatus(): void {
    this.get(statusEndpoint).subscribe(raw => { this.status$.next(raw); });
  }

  public get(endpoint: string): Observable<HttpResponse<any>> {
    return this.http.get(backendUrl + endpoint);
  }

(...)

到目前为止,一切都很好。现在我想让其他服务依赖该BackendService.get方法,这将是处理超时、错误处理和其他类似事情的中心位置。

现在,当我在另一个服务中定义此服务时,如下所示:

import { Injectable } from '@angular/core';

import { BackendService } from './backend.service';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  constructor(
    private backend: BackendService,  // <-- here!
  ) { }

然后编译没有错误,但我得到以下控制台错误:

ERROR Error: Cannot instantiate cyclic dependency! AuthService
    Angular 7
    UserPanelComponent_Factory user-panel.component.ts:12
    Angular 5
        getNodeInjectable
        instantiateAllDirectives
        createDirectivesInstances
        elementStart
        element
    AppComponent_Template app.component.html:4
    Angular 20
core.js:6241:19

在哪里user-panel.component.ts进口AuthService

import { Component, OnInit } from '@angular/core';

import { AuthService, Credentials } from '../auth.service';
import { UserService, UserDetails } from '../user.service';


@Component({
  selector: 'app-user-panel',
  templateUrl: './user-panel.component.html',
  styleUrls: ['./user-panel.component.scss']
})
export class UserPanelComponent implements OnInit {
  public userDetails: UserDetails;

  constructor(
    public auth: AuthService,
    public user: UserService,
  ) {}

  ngOnInit(): void {
    // trigger refresh from local storage once the component is ready
    this.auth.initializeFromStorage();
  }

  onLogOut() {
    this.auth.logUserOut();
  }

}

所以问题:如何将服务导入另一个服务?

注释:

标签: angulartypescript

解决方案


“经典”是使用 Injector 获取对新 BackendService 的引用

private backend: BackendService
constructor (injector:Injector) {
    this.backend = injector.get(BackendService);
}

推荐阅读