如何解决循环依赖

Dmi*_*nko 10 angular

我有3项服务:

auth.service.ts,account.service.ts,http.service.ts

用户注册时我应该创建新帐户,因此我将account.service.ts导入auth.service.ts.我应该这样做,因为我使用注册表单数据来创建一个新帐户.

@Injectable()
export class AuthService {
  constructor(public accountService: AccountService) {}

  signUp(name: string, phone: string, email: string, password: string): void {

    ...

  userPool.signUp(phone, password, attributeList, null, (err: any, result: any) => {
  if (err) {

    ...

    return;
  }

  this.accountService.createAccount(name, phone, email).subscribe(res => {

    ...

    this.router.navigate(['/auth/confirmation-code']);
  });
});
Run Code Online (Sandbox Code Playgroud)

}

因此,当我使用AWS Cognito时,我应该将auth.service.ts中的授权令牌添加到http.service.ts,因此我将auth.service.ts导入到http.service.ts.

@Injectable()
export class HttpService {
  private actionUrl: string;
  private headers: Headers;
  private options: RequestOptions;

  constructor(
    public _http: Http,
    public authService: AuthService 
  ) {
    this.actionUrl = 'https://example.com/dev';
    this.headers = new Headers();

    this.authService.getAuthenticatedUser().getSession((err: any, session: any) => {
      if(err) return;
      this.headers.append('Authorization', session.getIdToken().getJwtToken());
    });

    this.headers.append('Content-Type', 'application/json');
    this.headers.append('Accept', 'application/json');
    this.headers.append('Access-Control-Allow-Headers', 'Content-Type, X-XSRF-TOKEN');
    this.headers.append('Access-Control-Allow-Origin', '*');

    this.options = new RequestOptions({ headers: this.headers });
  }

    get(request: string): Observable<any> {
        return this._http.get(`${this.actionUrl}${request}`)
            .map(res => this.extractData(res))
            .catch(this.handleError);
   }
Run Code Online (Sandbox Code Playgroud)

在我的account.service.ts中,我应该使用http.service.ts来创建新帐户.

@Injectable()
export class AccountService {
  constructor(public httpService: HttpService) {}
Run Code Online (Sandbox Code Playgroud)

检测到循环依赖项中的警告:src/app/core/services/account.service.ts - > src/app/core/services/http.service.ts - > src/app/core/services/auth.service.ts - > src/app/core/services/account.service.ts

检测到循环依赖项中的警告:src/app/core/services/auth.service.ts - > src/app/core/services/account.service.ts - > src/app/core/services/http.service.ts - > src/app/core/services/auth.service.ts

检测到循环依赖项中的警告:src/app/core/services/http.service.ts - > src/app/core/services/auth.service.ts - > src/app/core/services/account.service.ts - > src/app/core/services/http.service.ts

据我所知,这是循环依赖错误.怎么解决?最佳实践?所有服务都履行其职责并且非常重要.

Mar*_*mek 10

你可以用Injector它.像往常一样通过构造函数注入它,然后当您需要一些导致循环依赖的服务时,从中获取该服务.

class HttpService {
  constructor(private injector: Injector) { }

  doSomething() {
    const auth = this.injector.get(AuthService);
    // use auth as usual
  }
}
Run Code Online (Sandbox Code Playgroud)

  • `HttpService` 仍然有一个对 `AuthService` 的引用(它在 `injector.get` 方法中用作 Type。那么这如何解决循环依赖呢?文件、服务、类仍然相互引用。 (3认同)
  • @MartinAdámek,根据我的经验,这不是真的。总有办法不陷入这个问题,尽管有时很难看到它。我通常做的是引入更多的抽象层和/或在组件之间移动职责,有时通过引入更多的组件。然而,这种方法不是灵丹妙药,必须非常小心地使用,否则抽象层的数量会导致很大的混乱,但在这种情况下它是有道理的。 (2认同)
  • 无论如何,如果问题出在身份验证上,则最好使用HttpInterceptor进行此操作,这可以在运行中向每个请求添加必要的标头。 (2认同)

Ash*_*lot 8

@deprecated 从 v4.0.0 使用 Type 或 InjectionToken

const auth = this.injector.get(AuthService);
Run Code Online (Sandbox Code Playgroud)

适用于 Angular 10:

const AuthService = this.injector.get<AuthService>(AuthService);
Run Code Online (Sandbox Code Playgroud)


Wah*_*hah 5

只是想分享一个发生在我身上的场景(也许它可以帮助某人)。所以我也遇到了相同的循环依赖错误和空注入器错误。唯一让我头晕的是我只有一个服务,并且不存在字面上的循环依赖。

所以我只是尝试查看空注入器错误,问题是在我的app.moduleI 中没有导入HttpClientModule. 一旦我将其导入到导入数组中,两个错误都得到了修复。