推荐答案
在 Nest.js 中,依赖注入(Dependency Injection, DI)是通过 @Injectable() 装饰器和构造函数注入来实现的。以下是一个简单的示例:
// www.javascriptcn.com code example
import { Injectable } from '@nestjs/common';
@Injectable()
export class CatsService {
private readonly cats: string[] = ['Milo', 'Whiskers'];
findAll(): string[] {
return this.cats;
}
}然后,在控制器或其他服务中通过构造函数注入:
// www.javascriptcn.com code example
import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
@Controller('cats')
export class CatsController {
constructor(private readonly catsService: CatsService) {}
@Get()
findAll(): string[] {
return this.catsService.findAll();
}
}本题详细解读
1. @Injectable() 装饰器
@Injectable() 装饰器用于标记一个类为可注入的。这意味着 Nest.js 的依赖注入系统可以管理这个类的实例,并在需要时将其注入到其他类中。
@Injectable()
export class CatsService {
// ...
}2. 构造函数注入
在 Nest.js 中,依赖注入通常通过构造函数来实现。当你在构造函数中声明一个参数时,Nest.js 会自动解析并注入相应的依赖。
constructor(private readonly catsService: CatsService) {}在这个例子中,CatsService 会被自动注入到 CatsController 中。
3. 模块注册
为了使依赖注入正常工作,你还需要在模块中注册提供者(Provider)。提供者通常是服务类,但也可以是其他类型的类或值。
// www.javascriptcn.com code example
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}在这个模块中,CatsService 被注册为一个提供者,因此它可以在 CatsController 中被注入。
4. 依赖注入的作用域
Nest.js 中的依赖注入支持不同的作用域(Scope),包括单例(Singleton)、请求作用域(Request-scoped)等。默认情况下,所有提供者都是单例的,这意味着它们在应用程序的整个生命周期中只会被实例化一次。
5. 自定义提供者
除了类提供者外,Nest.js 还支持自定义提供者,例如工厂提供者、值提供者等。这些提供者可以通过 useFactory、useValue 等选项来定义。
// www.javascriptcn.com code example
@Module({
providers: [
{
provide: 'CONNECTION',
useFactory: () => {
return new DatabaseConnection();
},
},
],
})
export class DatabaseModule {}在这个例子中,CONNECTION 是一个自定义提供者,它通过工厂函数来创建 DatabaseConnection 的实例。
通过以上方式,Nest.js 提供了强大而灵活的依赖注入机制,使得代码更加模块化和可测试。