首页 > 其他分享 >【NestJS系列】核心概念:Providers提供者

【NestJS系列】核心概念:Providers提供者

时间:2023-07-29 21:05:02浏览次数:30  
标签:依赖 return nanjiu 提供者 NanjiuService Providers NestJS class 注入

前言

ProvidersNest中的一个基本概念,许多Nest中定义的类都可以被视为一个Provider,比如:service、repository、factory、helper等,它们都可以通过constructor注入依赖关系,这就意味着类与类之间可以创建各种依赖关系,并且维护各个类之间依赖关系的工作将委托给Nest运行时系统。

Provider类(service)基本用法

前面几章我们通过nest-cli生成的代码中就包含有service

比如:

// nanjiu.service.ts
import { Injectable } from '@nestjs/common';
import { CreateNanjiuDto } from './dto/create-nanjiu.dto';
import { UpdateNanjiuDto } from './dto/update-nanjiu.dto';

@Injectable()
export class NanjiuService {
  create(createNanjiuDto: CreateNanjiuDto) {
    return 'This action is nanjiu post';
  }

  findAll() {
    return `This action returns all nanjiu`;
  }

  findOne(id: number) {
    return `This action returns a #${id} nanjiu`;
  }

  update(id: number, updateNanjiuDto: UpdateNanjiuDto) {
    return `This action updates a #${id} nanjiu`;
  }

  remove(id: number) {
    return `This action removes a #${id} nanjiu`;
  }
}

使用步骤如下:

@Injectable()装饰器

这里的NanjiuService类通过@Injectable装饰器标记为一个provider,表明该类可以被NestIOC容器管理

在module中注册

服务需要在对应的module中进行注册,如果不注册IOC容器是不会帮你创建对象的,而且还会报错

// nanjiu.module.ts
@Module({
  controllers: [NanjiuController],
  providers: [NanjiuService]
})
export class NanjiuModule {}

在controller中注入并使用

module中注册service类后,再通过controller的构造函数进行注入,那么该类就可以在controller中去使用了

// nanjiu.controller.ts

@Controller('nanjiu')
export class NanjiuController {
  constructor(private readonly nanjiuService: NanjiuService) {}

  @Post()
  @Header('Cache-Control', 'none')
  create(@Body() createNanjiuDto: CreateNanjiuDto) {
    console.log('body', createNanjiuDto)
    return this.nanjiuService.create(createNanjiuDto);
  }
}

可以看到是通过类构造函数 constructor(private readonly nanjiuService: NanjiuService) {}这种方式来进行依赖注入的,Nest提供了IOC容器利用Typescript自带类型的特点自动创建对象的能力,注意这里是单例模式,如果该Service在其它地方也被用过,那么会在不会重新创建对象,各个应用只会有一个该Service的对象,容器会先寻找当前有没有,如果没有再进行创建。

自定义Provider

Provider可以是一个值(value),也可以是一个类(class),还可以是一个工厂函数(factory)

useClass

上面providers的那种写法其实是一种简写,它的完整写法应该是这样:

// nanjiu.module.ts
@Module({
  controllers: [NanjiuController], // 控制器
  providers: [{
    provide: 'NANJIU',  // 自定义依赖注入的标识
    useClass: NanjiuService // 依赖注入的类
  }]
})
export class NanjiuModule {}

完整写法可以通过provide属性给不同的provider标注不同的token

然后再controller中需要使用@Inject(对应的token)进行注入

// nanjiu.controller.ts
@Controller('nanjiu')
export class NanjiuController {
  constructor(@Inject('NANJIU') private readonly nanjiuService: NanjiuService) {}

  @Post()
  @Header('Cache-Control', 'none')
  create(@Body() createNanjiuDto: CreateNanjiuDto) {
    console.log('body', createNanjiuDto, this.nanjiuService)
    return true
    return this.nanjiuService.create(createNanjiuDto);
  }
}

useValue

还可以使用useValue自定义注入值

// nanjiu.module.ts
@Module({ // 模块装饰器
  controllers: [NanjiuController], // 控制器
  providers: [{
    provide: 'NANJIU',  // 自定义依赖注入的标识
    useValue: {
      name: 'nanjiu' // 依赖注入的值
    }
  }]
})

【NestJS系列】核心概念:Providers提供者_依赖注入

useFactory

工厂函数可以提供动态的provider,由factory函数的返回值来确定,factory函数可以很简单也可以很复杂,它也可以使用其它provider,不过需要在inject属性进行注入,注入的provider可以是可选的

  • 工厂函数可以接受(可选)参数。
  • (可选)inject属性接受一组提供程序,Nest 将在实例化过程中解析这些提供程序并将其作为参数传递给工厂函数。这两个列表应该是相关的:Nest 将以inject相同的顺序将列表中的实例作为参数传递给工厂函数。
// nanjiu.module.ts
import { Module } from '@nestjs/common';
import { NanjiuService } from './nanjiu.service';
import { UserService } from 'src/user/user.service';
import { NanjiuController } from './nanjiu.controller';

@Module({ // 模块装饰器
  controllers: [NanjiuController], // 控制器
  providers: [{
    provide: 'NANJIU',  // 自定义依赖注入的标识
    useClass: NanjiuService // 依赖注入的类
  },
  UserService,
  {
    provide: 'USER', // 自定义依赖注入的标识
    useFactory: (...args) => { // 工厂模式
      console.log('useFactory', args)
      return new UserService() // 依赖注入的类
    },
    inject: [UserService] // 依赖注入的类
  }

]
})
export class NanjiuModule {}

【NestJS系列】核心概念:Providers提供者_ide_02

可选的Provider

有时你可能存在不一定需要解决的依赖关系。例如,你的类可能依赖于配置对象,但如果没有传递任何内容,则应使用默认值。在这种情况下,依赖关系变得可选,这时候可以给对应的注入服务再增加一个@Optional()装饰器就行

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}

异步Provider

useFactory可以返回一个promise 或者其他异步操作,Nest 将在实例化任何依赖(注入)此类提供程序的类之前等待promise的结果。

// nanjiu.module.ts
@Module({ // 模块装饰器
  controllers: [NanjiuController], // 控制器
  providers: [
  UserService,
  {
    provide: 'USER', // 自定义依赖注入的标识
    useFactory: async () => { // 工厂模式
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(new UserService())
        }, 1000)
      })
    },
    inject: [UserService] // 依赖注入的类
  }

]
})
export class NanjiuModule {}

标签:依赖,return,nanjiu,提供者,NanjiuService,Providers,NestJS,class,注入
From: https://blog.51cto.com/u_13756259/6895133

相关文章

  • 【NestJS系列】从Nest CLI开始入门
    初识NestJSNest是一个渐进的Node.js框架,它可以在TypeScript和JavaScript(ES6、ES7、ES8)之上构建高效、可伸缩的企业级服务器端应用程序。Nest基于TypeScript编写并且结合了OOP(面向对象编程),FP(函数式编程)和FRP(函数式响应编程)的相关理念。在设计上的很多灵感来自于Ang......
  • Node-框架NestJS入门使用
     前言介绍Nest是一个用于构建高效,可扩展的Node.js服务器端应用程序的框架。它使用渐进式JavaScript,使用TypeScript构建(保留与纯JavaScript的兼容性),并结合了OOP(面向对象编程),FP(功能编程)和FRP(功能反应编程)的元素。注意请确保你的操作系统上安装了 Node.js(版本>=16)和 npm官......
  • 【NestJS系列】核心概念:Controller控制器
    前言控制器主要是用来处理客户端传入的请求并向客户端返回响应。它一般是用来做路由导航的,内部路由机制控制哪个控制器接收哪些请求。路由为了创建基本控制器,我们需要使用@Controller装饰器,装饰器将类与所需元数据关联起来,并使Nest能够创建路由映射。我们使用nest-cli快速创......
  • These are the list of external providers available to the application.
    Thesearethelistofexternalprovidersavailabletotheapplication.https://github.com/davidfowl/TodoApi/blob/c209f6ae5c5f31f4808b0df85f358d4a572ea770/Todo.Web/Server/Authentication/AuthenticationExtensions.cs#L42 ......
  • 【NestJS系列】DI依赖注入与IOC控制反转
    前言上篇文章我们学习了如何使用nest-cli来快速生成一个NestJS后端项目,当我们打开编辑器查看代码时,会发现整个代码风格有点类似JAVA的spring框架,并且你会发现一些service类在controller控制器的constructor中注入后,可以不需要手动new就可以直接使用该类对应的实例方法。比如:imp......
  • NestJs 集成 OIDC
    要将OIDC集成到NestJS中,可以按照以下步骤进行操作:首先,确保已经安装了@nestjs/passport和passport这两个依赖包,以便使用Passport和OIDC策略。npminstall--save@nestjs/passportpassport然后,安装用于OIDC的Passport策略包。这里以passport-openidconnect......
  • nestjs入门学习 | day2
    nestjs入门学习|day2day2:nest基础知识点学习:中间件、异常过滤器、守卫、管道、拦截器中间件Nest中间件可以是一个函数,也可以是一个带有@Injectable()装饰器的类,且该类应该实现NestMiddleware接口,而函数没有任何特殊要求。如下是一个日志中间件的简单示例:import{......
  • nestjs入门学习 | day1
    nestjs入门学习|day1day1:为什么要用nestjs,和egg区别对比nest项目初始化,了解目录结构nestcli命令了解nest基础知识点学习:控制器、服务、模块为什么要用nestjs,和egg区别对比官网介绍Nest提供了一种开箱即用的应用程序架构,允许开发人员和团队创建高度可测试、可扩展......
  • 【NestJS系列】从Nest CLI开始入门
    初识NestJSNest是一个渐进的Node.js框架,它可以在TypeScript和JavaScript(ES6、ES7、ES8)之上构建高效、可伸缩的企业级服务器端应用程序。Nest基于TypeScript编写并且结合了OOP(面向对象编程),FP(函数式编程)和FRP(函数式响应编程)的相关理念。在设计上的很多灵感来自于......
  • React18+TS+NestJS+GraphQL 全栈开发在线教育平台
    第1章这里,将带你进行一次全面,高效的进阶试看3节‖36分钟学习本课程你能得到什么?不论是技术提升,职场晋升,面试跳槽,你都会有所收获。第2章了解用户需求,懂得如何做项目试看4节‖54分钟本章让大家了解一个企业级项目的用户需求是什么,有哪几种角色,是如何使用我们的产品的,知道......