Open1

NestJS

bigbigcatatmospherebigbigcatatmosphere

NestJSのModuleの動作

Moduleのイメージ

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  imports: [, ....]
  controllers: [CatsController],
  providers: [CatsService],
  exports: [, ....]

})
export class CatsModule {}

Controler/Provider(Service)の生成に必要な処理

各Moduleクラスでは以下を宣言する。
the set of controllers defined in this module which have to be instantiatedと記載があるように、使いたいService, ControllerはいずれかのModuleのcontrollers, providersに記載する必要がある。

providers the providers that will be instantiated by the Nest injector and that may be shared at least across this module

controllers the set of controllers defined in this module which have to be instantiated

Moduleの階層構造による記述の簡略化

Moduleは階層にすること、共通Moduleを作ることが、想定されている。
つまり、別のModuleにてインスタンス生成を定義したController/ServiceをDIしたいケース。
この場合は、記述にある通り、必要な対応は以下の通り

  1. 呼び出し元のModuleで、生成したいController/Service/Moduleを紐づけたModuleをimportする
  2. (Serviceの場合)呼び出し先ModuleでexportsにServiceを記載する

imports the list of imported modules that export the providers which are required in this module

exports the subset of providers that are provided by this module and should be available in other modules which import this module. You can use either the provider itself or just its token (provide value)

これで、呼び出し元のModuleでは、生成したい別ModuleのService(ServiceAとすると)を記載しなくても、当該Module二直接紐づけた、controller/Serviceに対して、ServiceAをDIできる

@Module({
  providers: [ServiceA],
  exports: [ServiceA]
})
export class ServiceAIncludeModule {}

@Module({
  imports: [ServiceAIncludeModule]   
  controllers: [CatsController], 
  providers: [CatsService],
 // ServiceAIncludeModuleをimportするだけでCatsController/CatsServiceにServiceAをDIできる
})
export class CatsModule {}

ModuleのScope

Moduleのimport, exportのscopeはそのmodule内に限られるので、孫moduleは参照できない

親 import:==> 子 import ==> 孫
としても親から孫を参照できない

これをやりたい場合、子moduleにて 孫moduleを再exportする必要がある

@Module({
 imports: [孫Module],
 expots: [孫Module]
})
export class 子Module {}

@Module({
 imports: [子Module],
 controlles: [親Controller]
 providers: [親Service]
})
export class 親Module {}
// こうすれば 親Moduleにて動作する親Service, 親Controllerでは孫servivceをDIできる