@NgModuleのimports内でInjectionTokenを使いたい

ライブラリを作成していて、このライブラリが使われるときに、例えばAPIキーとかアクセストークンとかを使用側から注入できるように、以下のようなInjectionTokenを作成しました。

export interface Config {
     agmApiKey: string;
 }

export const CONFIG = new InjectionToken<Config>('Config');

このInjectionTokenを(ライブラリの)@NgModuleのimports内で使いたいときの使い方がわかりません

library.module.ts

@NgModule({
  declarations: [
  ],
  imports: [
    AgmCoreModule.forRoot({
      apiKey: config.agmApiKey  // ←ここの書き方がわかりません
    }),
  ],

コンポーネントとかサービスのコンストラクタで

@Inject(CONFIG) config: Config

で注入された値を使うのはやったことがあります。

よろしくお願いいたします。

自作のNgModuleのstaticメソッドで受け取った値をプロバイダーに設定したいということですよね
ライブラリかどうかは影響のないことなので通常のNgModuleと同じように providers を使った書き方で良いと思います。

https://angular.jp/guide/dependency-injection-providers#using-an-injectiontoken-object

この時点では値が決まっていなくて、このライブラリを使うときに使用側のprovidersで

{provide: CONFIG, useValue: REAL_CONFIG_VALUE}

で値を決定したいという感じです。

@NgModule({
  declarations: [
  ],
  imports: [
    AgmCoreModule.forRoot({
      apiKey: config.agmApiKey
    })
  ],
  exports: [
  ]
})
export class SharedModule {
  constructor(
    @Inject(CONFIG) config: Config
  ) {}
}

アノテーション内でconfigを参照できなくて、うまくいきませんでした。

ああ、AgmCoreModule は自作のライブラリではないのですね

そもそも、 SharedModule がアプリケーションのルートモジュールで読み込まれる保証がないので、ライブラリがアプリケーションの代わりにサードパーティの forRoot() を呼び出すこと自体を避けるべきだと思います。自作ライブラリのNgModuleに forRoot() メソッドを作成し、その中でサードパーティライブラリが提供するAPIに従ってDIプロバイダーを設定することになると思います。

1 Likes

なるほど!
それならドキュメントを参考にしつつできそうな気がします。
このような事例のサンプルコードがどこにも載ってなかった理由がわかりました。
ありがとうございます。