中断使用useFactory属性创建的循环引用

时间:2019-05-16 19:30:48

标签: angular typescript

我有一个可注入服务,该服务使用useFactory属性来控制它是否被注入,或者是否注入了实现的类型。

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { signatureConfigurationServiceFactory } from '../../environments/services.factories';
import { RestService } from '.';

@Injectable({
  providedIn: 'root',
  useFactory: signatureConfigurationServiceFactory,
  deps: [Router, RestService]
})
export class SignatureConfigurationService {

  constructor(public router: Router, public restService: RestService) {
  }

  // ... 
}

工厂是在另一个文件services.factories.ts中定义的,因为我希望能够在fileReplacements期间用包含另一个工厂的另一个类似文件,用ng build替换该文件。

import { Router } from '@angular/router';
import { RestService } from '../app/services';
import { SignatureConfigurationService } from '../app/services/signature-configuration.service';

export let signatureConfigurationServiceFactory = (router: Router, restService: RestService) => {
  return new SignatureConfigurationService(router, restService);
};

由于我的服务引用了工厂,而工厂引用了服务,因此我在这里得到了循环引用。

Angular文档提到使用forwardRef,但是文档中的示例不适用于我的情况。

如何在将工厂方法保存在单独文件中的同时打破这种循环依赖关系?

2 个答案:

答案 0 :(得分:0)

我找到了解决方案。

A创建了名为ServiceFactoriesRegistry的第三类,该类包含所有工厂函数作为类型的静态属性,该类型是返回any的函数,因此我们不必导入包含以下内容的文件:服务。

import { Router } from '@angular/router';
import { RestService } from '.';

export class ServiceFactoriesRegistry {
  public static signatureConfigurationServiceFactory: (router: Router, restService: RestService) => any;
}

我更改了包含工厂功能的先前文件,以将工厂方法分配给此新注册表。 services.factories.ts这个文件,将在构建时替换,它同时依赖于工厂方法和服务。

import { Router } from '@angular/router';
import { RestService } from '../app/services';
import { ServiceFactoriesRegistry } from '../app/services/service-registry';
import { SignatureConfigurationService } from '../app/services/signature-configuration.service';

export function registerServices() {
  ServiceFactoriesRegistry.signatureConfigurationServiceFactory = (router: Router, restService: RestService) => {
    return new SignatureConfigurationService(router, restService);
  };
}

此导出函数在我的AppModule中调用:

export class AppModule {
  constructor() {
    registerServices();
  }
}

在服务本身中,我使用了工厂注册表。虽然我依赖注册表,但是服务工厂方法本身却没有,因为它是在其他地方注册的。

@Injectable({
  providedIn: 'root',
  useFactory: ServiceFactoriesRegistry.signatureConfigurationServiceFactory,
  deps: [Router, RestService]
})
export class SignatureConfigurationService

答案 1 :(得分:-2)

您不必声明要在构造函数中注入的变量。当您执行此操作时,实际上是在声明两次。

因此更改此

export class SignatureConfigurationService {
router: Router;
restService: RestService;

constructor(router: Router, restService: RestService) {
this.router = router;
this.restService = restService;
}

更改为

export class SignatureConfigurationService {

  constructor(private router: Router,private restService: RestService) {}