Skip to content

服务提供者

类注册

js
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { MyService } from './my/my.service'

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

使用:

js
export class AppController() {
  constructor(private readonly MyService) {}
}

完整写法,可更改提供者名称

js
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { MyService } from './my/my.service'

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

使用:

js
export class AppController() {
  constructor(@Inject('myService') private readonly myService) {}
}

基本数据注册

js
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, { provide: 'config', useValue: { name: 'wxw', author: 'wxw' } }],
})
export class AppModule {}

使用:

js
export class AppController {
  constructor(@Inject('config') private readonly config) {}
}

动态加载模块

实现根据不同的环境创建不同的服务,首先需要获取 env 环境变量

bash
pnpm add dotenv

创建 app.service.tsmy.service.ts

根据不同环境变量动态设置服务

js
import path from 'node:path'
import { Module } from '@nestjs/common'
import { config } from 'dotenv'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { MyService } from './my/my.service'

config({ path: path.join(__dirname, '../.env') })

const appService = {
  provide: 'appService',
  useClass: process.env.NODE_ENV === 'development' ? AppService : MyService,
}
@Module({
  imports: [],
  controllers: [AppController],
  providers: [appService],
})
export class AppModule {}

使用工厂函数注册提供者

ts
@Module({
  providers: [
    AppService,
    ConfigService, //项目配置文件,其中有数据库连接参数
    {
      provide: 'DbService',
      inject: [ConfigService],
      useFactory(configService) {
        return new DbService(configService)
      }
    }
  ]
})

自定义 DbModule 接入 typegoose

GitHub 仓库地址,项目来源:全栈之巅视频课程

主要代码实现

js
// db.module.ts
import { DynamicModule, Module, Provider } from '@nestjs/common'
import { getModelForClass, mongoose } from '@typegoose/typegoose'
import { ConfigService } from '@nestjs/config'
import { DbService } from './db.service'

interface ClassType { new (...args: any[]): any }

@Module({})
export class DbModule {
  static forRoot(envKey: string, options = {}): DynamicModule {
    const providers: Provider[] = [
      {
        provide: 'DB_CONNECT',
        inject: [ConfigService],
        useFactory: (configService: ConfigService) => {
          const uri = configService.get < string > (envKey, 'MONGO_URI')
          return mongoose.connect(uri, options)
        },
      },
    ]
    return {
      module: DbModule,
      providers,
      exports: providers,
      global: true,
    }
  }

  static forFeature(models: ClassType[]): DynamicModule {
    const providers = models.map((model) => {
      return {
        provide: model.name,
        useFactory: () => getModelForClass(model),
      } as Provider
    })
    return {
      module: DbModule,
      providers,
      exports: providers,
      global: true,
    }
  }
}

异步服务提供者

ts
@Module({
  providers: [
    {
      provide: 'ConfigService',
      useFactory: async () => {
        return new Promise((resolve) => resolve(true))
      },
    },
  ]
})