Nest.js 系列——Provider 的多种引入方式

前言

Nest中使用了依赖注入的方式,来管理各个模块之间的依赖关系。在Nest中,提供了Provider来注入服务。但是引入有多种方式,这里来记录下每种方法的使用场景和要求。

通过类来引入

在前面知道,provider一般都是用@Injectable装饰的类

tsx 复制代码
@Injectable()
export class AppService {
  getWater(): string {
    return 'hello water'
  }
}

在模块的providers中,通过类来引入,比如服务这种提供者。

tsx 复制代码
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService]
})
export class AppModule {}

其实上面的提供者是一种简写方式,完整的写法如下:

tsx 复制代码
@Module({
  imports:[],
  controllers: [AppController],
  providers: [{
    provide: AppService,
    useClass: AppService,
  }],
})

通过 token 引入

通过 provide 指定注入的 token,通过 useClass 指定注入的对象的类,Nest 会自动对它做实例化再注入

tsx 复制代码
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getWater(): string {
    return this.appService.getWater()
  }
}

这里是使用的构造函数注入,也可以通过属性注入。

tsx 复制代码
@Controller()
export class AppController {
  @Inject()
  private readonly appService: AppService

  @Get()
  getWater(): string {
    return this.appService.getWater()
  }
}

通过@Inject装饰器来注入。指定注入的provider的token就行了,而且这个token还可以是一个字符串。

tsx 复制代码
@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: 'app_service',
      useClass: AppService
    }
  ]
})
export class AppModule {}

那么当token是字符串的时候,那么导入的方式就变成下面这样了。

tsx 复制代码
@Controller()
export class AppController {
  constructor(@Inject('app_service') private readonly appService: AppService) {}
  // 或者
  // @Inject('app_service')
  // private readonly appService: AppService;

  @Get()
  getWater(): string {
    return this.appService.getWater()
  }
}

指定一个值

除了指定一个类,还可以指定一个值,比如字符串,数字,布尔值等。

tsx 复制代码
@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: 'water_token',
      useValue: {
        name: 'water',
        age: 18
      }
    }
  ]
})
export class AppModule {}
tsx 复制代码
@Controller()
export class AppController {
  constructor(@Inject('water_token') private readonly waterToken: { name: string; age: number }) {}
}

也可以通过useFactory来动态生成一个值。

tsx 复制代码
@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: 'water_token',
      useFactory: () => {
        return {
          name: 'water',
          age: 18
        }
      }
    }
  ]
})
export class AppModule {}

使用方式与上面一致。同时使用useFactory还支持参数传递。

tsx 复制代码
{
    provide: 'water_token',
    useFactory: (name: string) => {
      return {
        name: name,
        age: 18,
      }
    },
    inject: ['name']
}

provide还可以通过useExisting来指定别名,比如把name这个provider的别名指定为water_token。

tsx 复制代码
@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: 'water_token',
      useExisting: 'name'
    }
  ]
})
export class AppModule {}

总结

通过类来引入,通过token来引入,通过useValue来引入一个值,通过useFactory来引入一个值,通过useExisting来引入别名。

以上就是Nest中Provider的多种引入方式。

相关推荐
QCoding29 分钟前
企业级Agent Evaluation实战:Agent能跑就能上线?AI Agent到底怎么测?
后端·spring
苍何1 小时前
让 WorkBuddy 操控浏览器,干活有点猛啊1
后端
IT_陈寒1 小时前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
XW1 小时前
常用提示词(Prompt)框架总结
后端
ServBay2 小时前
DeepSeek 再次崩了,DeepSeek V5正在路上?
后端·deepseek
IT规划师2 小时前
编程术语中的同步与异步:从"等不等"到工程取舍
后端·面试
孟陬3 小时前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
GoGeekBaird3 小时前
别再给每个 AI 做自我介绍了:我做了一个「个人上下文」管理系统
后端·github·agent
码事漫谈3 小时前
腾讯混元 Hy4 正式版发布了
后端
Mikko73 小时前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端