NestJs 提供者

发布时间 2023-03-31 16:30:15作者: makalo

文档:https://docs.nestjs.cn/9/providers

Providers 是 Nest 的一个基本概念。

许多基本的 Nest 类可能被视为

provider - service, repository, factory, helper 等等。

他们都可以通过 constructor 注入依赖关系。

这意味着对象可以彼此创建各种关系,

并且“连接”对象实例的功能在很大程度上可以委托给 Nest运行时系统。

Provider 只是一个用 @Injectable() 装饰器注释的类。

基本用法

如: 我们通过

nest g resource user

创建的user 模块

user.service.ts

import { Injectable } from '@nestjs/common';

// 提供者:Provider 只是一个用 @Injectable() 装饰器注释的类。
@Injectable()
export class UserService {}

module 里面已经引入 service 在 providers 注入

import { Module } from '@nestjs/common';
// 引入service
import { UserService } from './user.service';

@Module({
  // 提供者注入
  providers: [UserService]
})
export class UserModule {}

image-20230331143654181

在Controller 可以使用注入好的 Service 了

import { Controller } from '@nestjs/common';
// 引入service
import { UserService } from './user.service';

@Controller('user')
export class UserController {
    constructor(
    	// 注入service
        private readonly userService : UserService
    ){}
}

service 第二种用法 自定义名称

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

在 NestJs 中,默认情况下,服务名称是与服务类名相同的字符串。如果我们需要自定义服务名称,可以在 @Injectable() 装饰器中使用 provide 属性指定服务名称。

其实他全称是这样的

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';

@Module({
  controllers: [UserController],
  providers: [{
    provide: 'makalo_test',
    useClass: UserService
  }]
})
export class UserModule {}

自定义名称之后 需要用对应的@inject 取 不然找不到

constructor(@Inject('makalo_test') private readonly userService: UserService) {}

image-20230331154011214

自定义注入值

module.ts

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';

@Module({
  controllers: [UserController],
  providers: [
    {
      provide: 'makalo_test',
      useClass: UserService
    },
    {
      provide: "JD",
      useValue: ['TB', 'PDD', 'MT', 'ELM']
    }
  ]
})
export class UserModule { }

image-20230331154731067

controller.ts

import { Controller, Get, Post, Body, Patch, Param, Delete, Inject } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('user')
export class UserController {
  constructor(
    @Inject('makalo_test') private readonly userService: UserService,
    // 自定义注入的值
    @Inject('JD') private readonly shopList:string[]
  ) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.userService.create(createUserDto);
  }

  @Get()
  findAll() {
    // 使用
    return this.userService.findAll() + this.shopList;
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.userService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.userService.update(+id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.userService.remove(+id);
  }
}

image-20230331154851010

工厂模式

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

例:

我们将user.service 复制两份,分别命名为user.service2 和 3

image-20230331155240277

将 2 和 3 的类名改下,并将3的构造函数增加参数

constructor(userService2:UserService2){
    
}

module 里面注入

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { UserService2 } from './user.service2';
import { UserService3 } from './user.service3';

@Module({
  controllers: [UserController],
  providers: [
    {
      provide: 'makalo_test',
      useClass: UserService
    },
    {
      provide: "JD",
      useValue: ['TB', 'PDD', 'MT', 'ELM']
    },
    UserService2,
    {
      provide: "TestFactory",
      inject: [UserService2],
      useFactory(UserService2: UserService2) {
        return new UserService3(UserService2)
      }
    }
  ]
})
export class UserModule { }

image-20230331161226767

控制器里面使用

// 工厂模式
@Inject('TestFactory') private readonly testFactory:UserService3

image-20230331161513845

异步模式

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

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { UserService2 } from './user.service2';
import { UserService3 } from './user.service3';

@Module({
  controllers: [UserController],
  providers: [
    {
      provide: 'makalo_test',
      useClass: UserService
    },
    {
      provide: "JD",
      useValue: ['TB', 'PDD', 'MT', 'ELM']
    },
    UserService2,
    {
      provide: "TestFactory",
      inject: [UserService2],
      useFactory(UserService2: UserService2) {
        return new UserService3(UserService2)
      }
    },
    {
      provide: "sync",
      async useFactory() {
        return await  new Promise((r) => {
          setTimeout(() => {
            r('sync')
          }, 3000)
        })
      }
    }
  ]
})
export class UserModule { }

image-20230331161939803