Injicera en Nest.js-tjänst från en annan modul

Att injicera en tjänst från en annan Nest.js-modul innebär några steg för att säkerställa korrekt beroendeinjektion och modulorganisering. Använd två exempelmoduler för att lära dig hur processen att exportera och importera tjänster fungerar.

Genererar ett Nest.js-projekt

För att generera ett Nest.js-projekt måste du ha CLI installerat på din enhet. Om du inte gör det, kör det här kommandot för att installera det:

 npm install -g @nestjs/cli

Med Nest.js CLI installerad kör du det här kommandot för att generera ett nytt Nest.js-projekt:

 nest new <project-name>

Du kan ersätta ”” med vilket namn du väljer. Om du kör kommandot ovan genereras ett nytt Nest.js-projekt med det angivna namnet.

Din nuvarande projektstruktur bör se ut som bilden nedan:

För att öva på att injicera en tjänst från en modul till en annan modul, genererar du två moduler, modul-a och modul-b. Du kommer också att generera deras motsvarande tjänst- och kontrollfiler.

Kör detta kommando för att generera modul-a:

 nest generate module module-a

Och kör motsvarande kommando för modul-b:

 nest generate module module-b

Kör sedan det här kommandot för att generera tjänsten och styrenhetsfilerna för modul-a:

 nest generate service module-a && nest generate controller module-a

Och kör motsvarande kommando för modul-b:

 nest generate service module-b && nest generate controller module-b

Din nuvarande projektkatalog ska se ut så här, med katalogerna src/module-a och src/module-b:

Exportera en tjänst från modul A

För att exportera modul-a-tjänsten från modul-a-modulen måste du lista den som en export i modul-a:s modulfil (module-a.module.ts). Som standard tillhandahåller Nest.js CLI ingen exportmatris i @Module-dekoratorn, så den genererade modulfilen kommer att se ut så här:

 
import { Module } from '@nestjs/common';
import { ModuleAService } from './module-a.service';
import { ModuleAController } from './module-a.controller';

@Module({
  providers: [ModuleAService],
  controllers: [ModuleAController],
})

export class ModuleAModule {}

För att göra service-a (module-a.service.ts) tillgänglig för moduler som importerar modul-a, skapa en exportmatris i @Module-dekoratorn och lägg till ModuleAService till den.

Såhär:

 import { Module } from '@nestjs/common';
import { ModuleAService } from './module-a.service';
import { ModuleAController } from './module-a.controller';

@Module({
  providers: [ModuleAService],
  controllers: [ModuleAController],
  exports: [ModuleAService],
})

export class ModuleAModule {}

Lägg sedan till en enkel funktion i din modul-a-tjänstfil (module-a.service.ts), för teständamål:

 import { Injectable } from '@nestjs/common';

@Injectable()
export class ModuleAService {
  getHello(): string {
    return 'Hello from Module A!';
  }
}

Denna funktion returnerar en exempelsträng. För att bekräfta att du kan importera den här tjänsten korrekt kommer du att anropa den funktionen från modul-b efter att ha injicerat tjänst-a.

Importera en tjänst till modul B

För att importera en modul till en annan, måste du lista den som en import i den mottagande modulens importarray. I det här fallet måste du lägga till modul-a till importmatrisen för modul-b:s @Module-dekorator.

Som tidigare genererar Nest.js CLI inte automatiskt en importmatris, så du måste lägga till den manuellt.

Importera först den överordnade modulen (module-a.module.ts) till den mottagande modulen (module-b.module.ts), skapa importmatrisen och lägg till ModuleAModule till matrisen:

 
import { Module } from '@nestjs/common';
import { ModuleBController } from './module-b.controller';
import { ModuleBService } from './module-b.service';
import { ModuleAModule } from '../module-a/module-a.module';

@Module({
  imports: [ModuleAModule],
  controllers: [ModuleBController],
  providers: [ModuleBService],
})

export class ModuleBModule {}

Öppna sedan din module-b.service.ts-fil och importera Inject decorator och ModuleAServerice från @nests/common respektive ../module-a/module-a.service:

 import { Injectable, Inject } from '@nestjs/common';
import { ModuleAService } from '../module-a/module-a.service';

Injektionsdekoratorn markerar sin parameter som ett mål för beroendeinjektion.

Lägg sedan till kodblocket nedan i din ModuleBService-klass:

 @Inject(ModuleAService)
  private readonly moduleAService: ModuleAService;

Kodblocket ovan ger din ModuleBService tillgång till de metoder som finns tillgängliga i din ModuleAService.

Du kan testa tjänsten genom att anropa ModuleAServices getHello-metod.

 
import { Injectable, Inject } from '@nestjs/common';
import { ModuleAService } from 'src/module-a/module-a.service';

@Injectable()
export class ModuleBService {
  @Inject(ModuleAService)
  private readonly moduleAService: ModuleAService;

  getHello(): string {
    return this.moduleAService.getHello();
  }
}

Öppna sedan din module-b.controller.ts-fil och ersätt den genererade koden med kodblocket nedan:

 
import { Controller, Get } from '@nestjs/common';
import { ModuleBService } from './module-b.service';

@Controller('module-b')
export class ModuleBController {
  constructor(private readonly moduleBService: ModuleBService) {}

  @Get('/hello')
  getHello(): string {
    return this.moduleBService.getHello();
  }
}

Kodblocket ovan ställer in en GET-rutthanterare för getHello-funktionen.

Slutligen, gör en GET-förfrågan med curl till localhost:3000/module-b/hello. Kommandot ska skriva ut ”Hej från modul A!” till din konsol.

Du har framgångsrikt injicerat en tjänst i en annan modul. Detta kan vara praktiskt när du bygger API:er med Nest.js som har flera moduler som behöver anropa varandras metoder.

Fördelar med Cross-Module Injection

Även om att direkt anropa en tjänst från en annan modul kan verka enklare till en början, kan det leda till ett mer komplext, mindre underhållbart och mindre skalbart system i det långa loppet.

Korsmodulinjektion främjar dock kodmodularitet och återanvändbarhet, vilket gör det lättare att underhålla. Dessutom centraliserar den beroenden, förbättrar testbarheten och stöder en skalbar, frikopplad arkitektur.