添加提供程序后宣布AppModule

时间:2018-02-06 16:13:21

标签: javascript angular typescript angular-providers nswag

Angular 2+以下列方式注册提供者:

// @NgModule decorator with its metadata
@NgModule({
  declarations: [...],
  imports: [...],
  providers: [<PROVIDERS GO HERE>],
  bootstrap: [...]
})
export class AppModule { }

我想在此声明网站中单独注册应用程序范围的提供程序。

具体来说,我使用NSwag为我的整个Web API生成服务客户端,我想将它们全部动态添加为提供者。但是,我不确定如何执行此操作,因为@NgModule是应用于此AppModule类的属性。

这可能吗?

1 个答案:

答案 0 :(得分:1)

任何DI提供程序都需要在编译时包含在模块中。

由于Angular依赖注入与Typescript类型符号/标记一起使用,因此在编译之后没有Javascript功能来完成相同的任务。

您可以做的是在编译时动态添加提供程序,如下所示:

import { Load, SomeToken } from '../someplace';


@NgModule({
  declarations: [...],
  imports: [...],
  providers: [
    {
      provide: SomeToken,
      useValue: Load(someVariable)
  ],
  bootstrap: [...]
})
export class AppModule { }

然后在其他地方实现Load函数和令牌:

export const SomeToken = new OpaqueToken<any>('SomeToken');

export const Load = (someVariable) => {
  // logic to return an @Injectable here. Variable provided could be something like an environment variable, but it has to be exported and static
}

这种方法当然具有在编译时需要知道的限制。另一种方法是全局导入整个应用程序中所需的所有提供程序,无论环境如何,然后延迟加载组件,为该情况注入适当的提供程序(Angular将初始化提供程序,直到利用它的组件被初始化),或创建一个无论动态标准如何都能够执行逻辑的提供程序。一个想法是创建另一个服务,该服务利用该服务并根据该动态标准解析事物(即,您可以在第一个服务和第二个服务上使用名为GetLoginInfo的方法能够解析该方法的正确API调用。)

如果它只是您需要的API信息(即URL),那么您可以通过从config.json文件或API调用中获取URL信息来实现上述目的,并将这些值注入服务中,以便调用和令牌保持不变相同但使用不同的值。有关如何完成此操作的详细信息,请参阅here