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
相关推荐
2401_857622666 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589366 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
哎呦没7 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch7 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
杨哥带你写代码9 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
AskHarries9 小时前
读《show your work》的一点感悟
后端
A尘埃9 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-23079 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code9 小时前
(Django)初步使用
后端·python·django
代码之光_19809 小时前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端