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
相关推荐
zb200641203 小时前
CVE-2024-38819:Spring 框架路径遍历 PoC 漏洞复现
java·后端·spring
uzong3 小时前
AI Agent 是什么,如何理解它,未来挑战和思考
人工智能·后端·架构
追逐时光者3 小时前
DotNetGuide突破了10K + Star,一份全面且免费的C#/.NET/.NET Core学习、工作、面试指南知识库!
后端·.net
yuweiade3 小时前
springboot和springframework版本依赖关系
java·spring boot·后端
ywf12153 小时前
springboot设置多环境配置文件
java·spring boot·后端
小马爱打代码4 小时前
SpringBoot + 消息生产链路追踪 + 耗时分析:从创建到发送,全链路性能可视化
java·spring boot·后端
小码哥_常4 小时前
MyBatis批量插入:从5分钟到3秒的逆袭之路
后端
烛之武5 小时前
SpringBoot基础
java·spring boot·后端
橙序员小站5 小时前
Harness Engineering:从 OpenClaw 看 AI 助理的基础设施建设
后端·aigc·openai
小陈工6 小时前
2026年3月28日技术资讯洞察:5G-A边缘计算落地、低延迟AI推理革命与工业智造新范式
开发语言·人工智能·后端·python·5g·安全·边缘计算