nestjs 全栈进阶--provider

  视频教程

08_nest-provider1_哔哩哔哩_bilibili

前言

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

nest new provider -p pnpm
pnpm start:dev

1. 基本用法

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

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

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

还可以

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

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

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

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 容器来注入

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 创建一个返回配置对象的工厂函数

API_URL = xxx
API_KEY = xt
pnpm install @nestjs/config

在app.module.ts中使用

在app.controller中注入

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

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 或者其他异步操作

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

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

等3秒后

6. 别名

{
  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
  • 29
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@icapps/nestjs-prisma是一个基于Prisma ORM的NestJS模块,它可以帮助我们快速地集成Prisma ORM到NestJS应用程序中。如果你需要集成多个数据库,可以按照以下步骤进行: 1. 首先,在项目中安装Prisma ORM,并为每个数据库创建一个Prisma schema。 2. 创建一个新的Prisma client实例,该实例将连接到特定的数据库。你可以在NestJSproviders中创建多个Prisma服务,每个服务都使用不同的Prisma client实例。 3. 在使用@icapps/nestjs-prisma模块时,你可以将不同的Prisma服务注入到不同的模块或控制器中,以便在应用程序中访问多个数据库。 下面是一个简单的示例,展示了如何在NestJS应用程序中集成多个Prisma服务: ```typescript import { Module } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; import { PrismaService } from '@icapps/nestjs-prisma'; @Module({ providers: [ { provide: 'DB_ONE', useFactory: () => new PrismaClient({ datasources: { db: { url: 'XXXXXXXX' } } }), }, { provide: 'DB_TWO', useFactory: () => new PrismaClient({ datasources: { db: { url: 'XXXXXXXX' } } }), }, { provide: 'DB_THREE', useFactory: () => new PrismaClient({ datasources: { db: { url: 'XXXXXXXX' } } }), }, { provide: 'DB_FOUR', useFactory: () => new PrismaClient({ datasources: { db: { url: 'XXXXXXXX' } } }), }, PrismaService, ], }) export class AppModule {} ``` 在上面的示例中,我们创建了四个不同的Prisma服务,每个服务使用不同的Prisma client实例,并将它们的provider名称分别设置为`'DB_ONE'`、`'DB_TWO'`、`'DB_THREE'`和`'DB_FOUR'`。然后,我们将这些服务注入到应用程序的providers列表中,并为每个服务指定相应的Prisma client实例。最后,我们还将@icapps/nestjs-prisma的PrismaService也添加到providers中,以便在整个应用程序中访问Prisma服务。 当我们需要在控制器或模块中使用Prisma时,可以通过注入相应的Prisma服务来访问不同的数据库,例如: ```typescript import { Controller, Get, Inject } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; @Controller('users') export class UsersController { constructor( @Inject('DB_ONE') private readonly dbOne: PrismaClient, @Inject('DB_TWO') private readonly dbTwo: PrismaClient, @Inject('DB_THREE') private readonly dbThree: PrismaClient, @Inject('DB_FOUR') private readonly dbFour: PrismaClient, ) {} @Get() async getUsers() { const users1 = await this.dbOne.user.findMany(); const users2 = await this.dbTwo.user.findMany(); const users3 = await this.dbThree.user.findMany(); const users4 = await this.dbFour.user.findMany(); return { users1, users2, users3, users4 }; } } ``` 在上面的示例中,我们在控制器中注入了四个不同的Prisma服务,每个服务使用不同的Prisma client实例。然后,我们可以使用这些服务来查询不同的数据库,并将结果返回给客户端。 希望这个示例能够帮助你实现NestJS集成多个数据库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值