【问题标题】:Circle dependency of 3 services in AngularAngular中3个服务的循环依赖
【发布时间】:2019-03-13 14:00:30
【问题描述】:

我的 Angular 项目有问题。我收到以下警告:

WARNING in Circular dependency detected:
src\app\core\http\content.service.ts -> src\app\core\http\domain.service.ts -> 
src\app\shared\http\domain-shared.service.ts -> 
src\app\core\http\content.service.ts

我有 3 项服务:

Content Service 使用该方法获得了我的数据库的一堆代码

getContentCodes()
  constructor(
    private httpClient: HttpClient,
    private tokenService: TokenService,
    private domainService: DomainService
  ) {
    this.externalToken = new Token();
    this.domainData = this.domainService.getDomainData() as DomainData;
  }

Domain Service 我有代码从这个实例或存储中获取值

  constructor(private storageBrowser: StorageBrowser, private domainSharedService: DomainSharedService) {
    this.init();
  }

  getDomainData(): DomainData {
    if (this.domainData && Object.values(this.domainData).length > 0) {
      return this.domainData;
    }

    let domain = this.storageBrowser.get(StorageVariables.DOMAIN_DATA);
    if (!domain) {
       domain = this.checkForDomain();
    }

    this.domainData = new DomainData(domain);
    return this.domainData;
  }

  setDomainDataItem(item: DomainItem) {
    this.domainData.setDomainItem(item);
    this.storageBrowser.set(StorageVariables.DOMAIN_DATA, this.domainData, true);
  }

  async checkForDomain(): Promise<DomainData> {
    return await this.domainSharedService.checkDomainData();
  }

最后我有了Domain Shared 服务,我将在其中发出 HTTP 请求以获取域数据值

constructor(private clubService: ClubService, private content: ContentService) {
    this.domainCalls = [];
}

async checkDomainData(): Promise<DomainData> {
    const whiteList: string[] = await this.content.getContentCodes();
    const clubLevels: ClubLevel[] = await this.clubService.getClubLevels();
    this.domainCalls = [{ code: 'clubLevels', value: clubLevels.reverse() }, { code: 'whiteList', value: whiteList}];
    const domainItems: DomainItem[] = this.setItems(this.domainCalls);
    const domainData: DomainData = new DomainData();
    domainData.data = domainItems;
    return domainData;
}

内容使用域服务来获取在注入域共享服务的域服务中检查的域共享值。并在此域共享服务中注入内容以使用 getContentCodes() 获取白名单

有一种方法可以让这些服务相互通信,而不必注入它们或没有循环依赖?

谢谢

【问题讨论】:

  • 循环依赖通常是对糟糕设计的警告。您绝对应该检查您的架构,最终拆分为不同的类或服务。这里的名称太笼统,无法帮助您。
  • 请提供每个文件的导入部分,如果您使用 index.ts 导出它们,请也提供一个
  • @cgTag 让类相互依赖会破坏多个设计原则。并不是说这不可行,但我会在调整代码之前仔细审查类的设计以“避免问题”
  • @cgTag 没有比不想看到的盲人更糟糕的了。度过愉快而富有成效的一天。

标签: angular typescript circular-dependency


【解决方案1】:

您可以从 DomainSharedService 中的构造函数注入中删除 contentService,并将其用作 checkDomainData 中的参数,例如

async checkDomainData(content: ContentService): Promise<DomainData> {
   const whiteList: string[] = await content.getContentCodes();
   ...
}

要在组件中使用此服务,例如 FooComponent,

class FooComponent {
  constructor(private content: ContentService, private domainSharedService: DomainSharedService) {}
  someMethod() {
    this.domainSharedService.checkDomainData(this.content); 
  }
}

或者,您可以使用 Angular 注入器手动获取 contentService,例如在 DomainSharedService 中,

constructor(private injector: Injector, ...) {    }

async checkDomainData(): Promise<DomainData> {
  let content = this.injector.get(ContentService);
  const whiteList: string[] = await content.getContentCodes();
  ...
}

上述解决方法可以避免循环依赖。但正如其他人所说,这是一个糟糕的设计:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    相关资源
    最近更新 更多