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

By rik

För att använda en tjänst från en annan Nest.js-modul krävs några steg för att säkerställa korrekt beroendehantering och modulstruktur. Vi ska använda två exempelmoduler för att demonstrera hur tjänster exporteras och importeras.

Skapa ett Nest.js-projekt

För att starta ett nytt Nest.js-projekt behöver du ha Nest.js CLI installerat. Om du inte har det, installera det med följande kommando:

 npm install -g @nestjs/cli

När CLI är installerat, skapa ett nytt projekt med:

 nest new <project-name>

Ersätt ”projekt-namn” med det namn du väljer. Detta kommando skapar ett nytt Nest.js-projekt med det angivna namnet.

Din projektstruktur bör nu se ut ungefär så här:

För att öva på att injicera en tjänst från en modul till en annan skapar vi två moduler, ”module-a” och ”module-b”, samt deras tjänst- och kontrollfiler.

Skapa ”module-a” med kommandot:

 nest generate module module-a

Och skapa ”module-b” med:

 nest generate module module-b

Skapa sedan tjänsten och kontrollfilerna för ”module-a”:

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

Och motsvarande filer för ”module-b”:

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

Din projektkatalog bör nu inkludera mapparna ”src/module-a” och ”src/module-b”:

Exportera en tjänst från Modul A

För att exportera en tjänst från ”module-a” måste du ange den i ”exports”-delen av ”module-a.module.ts”. Som standard skapar inte Nest.js CLI detta, så din fil ser initialt 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 ”module-a.service.ts” tillgänglig för andra moduler som importerar ”module-a”, lägg till ”exports”-delen och inkludera ”ModuleAService”:

 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 till en enkel testfunktion i ”module-a.service.ts”:

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

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

Denna funktion returnerar en sträng. För att verifiera att importen fungerar kommer vi att anropa den här funktionen från ”module-b” efter att ha injicerat tjänsten.

Importera en tjänst till Modul B

För att importera en modul till en annan måste du ange den i ”imports”-delen av den mottagande modulen. I det här fallet lägger vi till ”module-a” i ”imports”-delen av ”module-b.module.ts”.

Som tidigare, skapar Nest.js CLI inte automatiskt en importmatris, så vi behöver skapa den manuellt.

Börja med att importera ”module-a.module.ts” i ”module-b.module.ts”, skapa importmatrisen och lägg till ”ModuleAModule”:

 
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 ”module-b.service.ts” och importera ”Inject”-dekoratören och ”ModuleAService” från respektive ”@nestjs/common” och ”../module-a/module-a.service”:

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

”Inject”-dekoratören markerar parametern för beroendeinjektion.

Lägg sedan till detta kodblock i ”ModuleBService”-klassen:

 @Inject(ModuleAService)
private readonly moduleAService: ModuleAService;

Detta block ger ”ModuleBService” tillgång till metoder i ”ModuleAService”.

Testa tjänsten genom att anropa ”ModuleAService”s ”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 nu ”module-b.controller.ts” och ersätt den existerande koden med:

 
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();
}
}

Denna kod sätter upp en GET-handler för ”getHello”-funktionen.

Slutligen, gör en GET-förfrågan med curl till ”localhost:3000/module-b/hello”. Kommandot ska returnera ”Hej från Modul A!” i konsolen.

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

Fördelar med Cross-Module Injection

Även om det kan verka enklare att anropa en tjänst direkt från en annan modul, kan detta leda till ett mer komplext, svårare att underhålla och mindre skalbart system i längden.

Cross-module injection främjar modulär kod och återanvändbarhet, vilket gör det enklare att underhålla. Dessutom centraliserar det beroenden, förbättrar testbarheten och underlättar en skalbar, frikopplad arkitektur.