前言

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' // 依赖注入的值
}
}]
})

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 {}

可选的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 {}

【NestJS系列】核心概念:Providers提供者的更多相关文章

  1. Spark系列-核心概念

    Spark系列-初体验(数据准备篇) Spark系列-核心概念 一. Spark核心概念 Master,也就是架构图中的Cluster Manager.Spark的Master和Workder节点分别 ...

  2. ZooKeeper 系列(一)—— ZooKeeper核心概念详解

    一.Zookeeper简介 二.Zookeeper设计目标 三.核心概念         3.1 集群角色         3.2 会话         3.3 数据节点         3.4 节点 ...

  3. ZooKeeper系列(一)—— ZooKeeper 简介及核心概念

    一.Zookeeper简介 Zookeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护.Zookeeper 可以用于实现分布式系统中常见的发布/订阅.负载均衡.命令服务.分布式协调 ...

  4. Storm 系列(二)—— Storm 核心概念详解

    一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的 Storm 流处理程序被称为 Storm topology(拓扑).它是一个是由 Spouts 和 Bolts 通过 Stre ...

  5. 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)

    一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...

  6. dubbo入门学习(一)-----分布式基础理论、架构发展以及rpc、dubbo核心概念

    一.分布式基础理论 1.什么是分布式系统? <分布式系统原理与范型>定义: “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统” 分布式系统(distributed ...

  7. [程序设计语言]-[核心概念]-02:名字、作用域和约束(Bindings)

    本系列导航 本系列其他文章目录请戳这里. 1.名字.约束时间(Binding Time) 在本篇博文开始前先介绍两个约定:第一个是“对象”,除非在介绍面向对象语言时,本系列中出现的对象均是指任何可以有 ...

  8. Redux 核心概念

    http://gaearon.github.io/redux/index.html ,文档在 http://rackt.github.io/redux/index.html .本文不是官方文档的翻译. ...

  9. SpaceSyntax【空间句法】之DepthMapX学习:第二篇 输出了什么东西 与 核心概念

    这节比较枯燥,都是原理,不过也有干货.这篇能不能听懂,就决定是否入门...所以,加油吧 博客园/B站/知乎/CSDN  @秋意正寒 转载请在文头注明本文地址 本篇讲空间句法的几个核心概念,有一些也是重 ...

  10. Eureka中的核心概念

    图片的链接出了一点小bug,导致图片不能正常访问,小伙伴们可以移步这里:https://mp.weixin.qq.com/s/kAqOTKUt_qPlxzI4aGS5Pw 本文是Spring Clou ...

随机推荐

  1. [Pytorch框架] 4.2.1 使用Visdom在 PyTorch 中进行可视化

    文章目录 4.2.1 使用Visdom在 PyTorch 中进行可视化 安装 坑 基本概念 Environments Panes VIEW 可视化接口 使用 绘制简单的图形 更新损失函数 import ...

  2. [Pytorch框架] 2.5 循环神经网络

    文章目录 2.5 循环神经网络 2.5.1 RNN简介 RNN的起因 为什么需要RNN RNN都能做什么 2.5.2 RNN的网络结构及原理 RNN LSTM GRU 2.5.3 循环网络的向后传播( ...

  3. sqlmap安全测试工具使用简介

    SQLmap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞,目前支持的数据库是MySQL,Oracle,PostgreSQL,Microsoft  SQL  S ...

  4. day08-优惠券秒杀04

    功能03-优惠券秒杀04 4.功能03-优惠券秒杀 4.7Redis优化秒杀 4.7.1优化分析 现在来回顾一下优惠券秒杀业务的两个主要问题: (1)首先是对优惠券的扣减,需要防止库存超卖现象: (2 ...

  5. windows10下编译32位和64位webrtc(m77)静态库

    1. windows10下编译32位和64位webrtc(m77)静态库 省略挂代理下载depot_tools以及webrtc代码的过程... 可参考webrtc编译 务必在 cmd 终端环境下进入到 ...

  6. 【开源游戏】Legends-Of-Heroes 基于ET 7.2的双端C#(.net7 + Unity3d)多人在线英雄联盟风格的球球大作战游戏。

    Legends-Of-Heroes 一个LOL风格的球球大作战游戏,基于ET7.2,使用状态同步  Main 基于C#双端框架[ET7.2],同步到ET主干详情请看日志.(https://github ...

  7. 【Visual Leak Detector】核心源码剖析(VLD 2.5.1)

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记.本篇对 VLD 2.5.1 源码做内存泄漏检测的思路进行剖析.同系列文章目录可见 <内存泄漏检测工具>目录 目录 说明 1. ...

  8. 2022-02-18:最大休假次数。 力扣想让一个最优秀的员工在 N 个城市间旅行来收集算法问题

    2022-02-18:最大休假次数. 力扣想让一个最优秀的员工在 N 个城市间旅行来收集算法问题. 但只工作不玩耍,聪明的孩子也会变傻,所以您可以在某些特定的城市和星期休假. 您的工作就是安排旅行使得 ...

  9. Selenium - 浏览器配置(3) - 沙盒模式/不打开浏览器运行

    Selenium - 浏览器配置 沙盒模式 需要在Linux环境中运行,但不需要打开浏览器进行UI测试,可以加载selenium的无痕模式: 如果使用沙盒模式运行selenium,则部分seleniu ...

  10. uni-app 创建项目及目录结构

    文件-新建-1.项目 ┌─uniCloud 云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud) │─components 符合vue组件规范的 ...