Angular DI:每个模块使用的每个服务实例

Angular DI: Instance of each service for each modul-usage

我有一个模块“FileUpload”。包含的上传服务“UploadService”获取注入了接口“RequestService”的服务。

我还有另外两个模块:FileManager1 和 FileManager2。每个文件管理器都提供自己的服务实现,其接口为“RequestService”,在令牌“REQUEST_SERVICE”中提供。

我为这个简化的场景创建了一个 stackblitz:https://angular-wufhd5.stackblitz.io

为了为每个模块使用创建自己的文件上传服务实例,我将服务提供者从文件-upload.module.ts 移到了组件 drop-zone.component.ts 中。正如您在 console.log.

中看到的那样有效

如果您点击“点击我”,FileManager1 和 FileManager2 的 console.log 输出相同。 ("Url2").

对于 FileManager1,它应该是 Url1,对于 FileManager2,它应该是 Url2。

满足此要求的干净解决方案是什么?我想避免在一个“REQUEST_SERVICE”旁边出现多个 takeens。

非常感谢!

点击事件后立即输出:

A new service has been created....
A new service has been created....
Angular is running in development mode. Call enableProdMode() to enable production mode.
Upload file to:
Url2
Upload file to:
Url2

输出应该:

A new service has been created....
A new service has been created....
Angular is running in development mode. Call enableProdMode() to enable production mode.
Upload file to:
Url1
Upload file to:
Url2

您可以像这样尝试针对每个模块提供商指定 RequestService:

@Injectable({
  providedIn: FileManager1Module ,
})
export class RequestService1 implements RequestService{
}

@Injectable({
  providedIn: FileManager2Module ,
})
export class RequestService2 implements RequestService{
}

并且在这些模块中的每个地方,您都可以通过接口 RequestService 注入它们。

Angular 只为 RootModule(AppModule) 和 lazy-loaded 模块创建 ModuleInjectors。直接导入模块的提供者升级到层次结构中的第一个 lazy-loaded 模块,或者如果有 none 到 RootModule。

因为您直接在 AppModule 中并按此顺序导入 FileManager1ModuleFileManager2Module。 Angular 首先升级到 AppModule 您在 FileManager1Module 中拥有的 REQUEST_SERVICE 的提供商。然后该提供程序将被您在 FileManager2Module 中拥有的提供程序覆盖。这就是为什么两者都将“Url2”打印到控制台的原因。

要解决它,你有两个选择:

  • REQUEST_SERVICE 声明为组件级提供程序。 (在 FileManager1ComponentFileManager2Component 中)
  • 或者,如果您打算使用路由器,Lazy-load 模块。

干杯