nestjs 全栈进阶--provider

视频教程

08_nest-provider1_哔哩哔哩_bilibili

前言

在 Nest.js 框架中,Providers 是一个核心概念,用于定义和管理应用中的服务、数据库连接、中间件、门面(facade)、仓库(repository)、工厂(factory)、帮助器(helper)等可注入的依赖。Providers 是 Nest.js 实现依赖注入(Dependency Injection, DI)体系的基础单元,它们可以被其他组件通过构造函数、属性注入等方式依赖,并由 Nest.js 的依赖注入容器自动管理和实例化。

arduino 复制代码
nest new provider -p pnpm
sql 复制代码
pnpm start:dev

1. 基本用法

可以看到 AppService 是被 @Injectable 修饰的 class

在 Module 的 providers 里声明,在 AppController 的构造器里参数里声明了 AppService 的依赖,就会自动注入。

如果不想用构造器注入,也可以属性注入:

还可以

2. providers第二种用法(自定义名称)

第一种用法就是一个语法糖

其实他的完整写法是这样的

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

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

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

当然,这个 token 也可以是字符串(不一定为app_service,你可以自定义为任何名称)

如果 token 是字符串的话,注入的时候就要用 @Inject 手动指定注入对象的 token 了

相比之下,用 class 做 token 可以省去 @Inject,比较简便。

3. 自定义注入值

除了指定 token 外,还可以直接指定一个值,让 IoC 容器来注入

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

@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: 'app_service',
      useClass: AppService,
    },
    {
      provide: 'person',
      useValue: {
        name: 'xt',
        age: 18
      }
    }
  ],
})
export class AppModule { }

使用 provide 指定 token,使用 useValue 指定值。然后再注入它

4. 工厂模式

在 Nest.js 中,useFactory 是一种特殊的提供商配置方式,它允许你在运行时动态创建一个服务实例,而不是直接实例化一个类

4.1. 动态配置加载: 当你需要从环境变量、配置文件或其他非静态来源获取配置数据时,可以使用 useFactory 创建一个返回配置对象的工厂函数

ini 复制代码
API_URL = xxx
API_KEY = xt
arduino 复制代码
pnpm install @nestjs/config

在app.module.ts中使用

在app.controller中注入

4.2. 如果服务 之间有相互的依赖 或者逻辑处理 可以使用 useFactory

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

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: ['.env'],
    }),
  ],
  controllers: [AppController],
  providers: [
    {
      provide: 'app_service',
      useClass: AppService,
    },
    {
      provide: 'person',
      useValue: {
        name: 'xt',
        age: 18
      }
    },
    {
      provide: 'app_config',
      useFactory: () => ({
        apiUrl: process.env.API_URL,
        apiKey: process.env.API_KEY,
      }),
    },
    AppService,
    {
      provide: 'app_test',
      inject: [AppService],
      useFactory(appService: AppService) {
        return {
          name: 'xt',
          desc: appService.getHello()
        }
      },

    }
  ],
})
export class AppModule { }

app_test 中要inject: [AppService], 所以我们得先在providers提供 AppService

5. 异步模式

useFactory 返回一个promise 或者其他异步操作

javascript 复制代码
{
      provide: "sync",
      useFactory: async () => {
        return await new Promise((resolve) => {
          setTimeout(() => {
            resolve('sync')
          }, 3000)
        })
      }
    }

Nest 会等拿到异步方法的结果之后再注入

等3秒后

6. 别名

css 复制代码
{
  provide: 'new_person',
  useExisting: 'person'
}

这里就是给 person 的 token 的 provider 起个新的 token 叫做 new_person。然后就可以用新 token 来注入了:

7. 总结

  • 一般情况下,provider 是通过 @Injectable 声明,然后在 @Module 的 providers 数组里注册的 class。
  • 默认的 token 是 class,这样不用使用 @Inject 来指定注入的 token。
  • 可以用字符串类型的 token,不过注入的时候要用 @Inject 单独指定。
  • 可以用 useClass 指定注入的 class,还可以用 useValue 直接指定注入的对象。
  • 动态生成对象,或依赖其他服务 可以使用 useFactory
  • 起别名,可以用 useExisting 给已有的 token,指定一个新 token
相关推荐
小码哥_常5 小时前
MyBatis-Plus:让数据库操作飞起来的神器
后端
2301_811274315 小时前
基于SpringBoot的智能家居管理系统
spring boot·后端·智能家居
AI人工智能+电脑小能手5 小时前
【大白话说Java面试题】【Java基础篇】第15题:JDK1.7中HashMap扩容为什么会发生死循环?如何解决
java·开发语言·数据结构·后端·面试·哈希算法
舒一笑5 小时前
我把设备指纹生成逻辑拆开了:它到底凭什么区分不同设备?
后端·程序员·掘金技术征文
Nicander6 小时前
多数据源下@transcation事务踩坑
java·后端
郑州光合科技余经理6 小时前
同城O2O海外版二次开发实战:从支付网关到配送算法
开发语言·前端·后端·算法·架构·uni-app·php
hamber6 小时前
用 Flutter 造一台掌机
flutter·ai编程·全栈
sjsjsbbsbsn7 小时前
大模型核心知识总结
java·人工智能·后端
Moment7 小时前
2026 年,AI 全栈时代到了,前端简历别再只写前端技术了 🫠🫠🫠
前端·后端·面试
白晨并不是很能熬夜8 小时前
【PRC】第 2 篇:Netty 通信层 — NIO 模型 + 自定义协议 + 心跳
java·开发语言·后端·面试·rpc·php·nio