一篇文章学会如何使用 NestJS 的五种 Provider 提供者

2024-01-03 04:20

本文主要是介绍一篇文章学会如何使用 NestJS 的五种 Provider 提供者,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

在构建复杂的后端应用中,如何有效地管理和彼此协作的各个部分,以及如何共享和复用功能已成为开发者们重要关注的问题。覆盖这些需求的一种技术就是 NestJS 中的 Providers。这次,让我们一起深入探讨这个关键概念,解密 Providers 的奥秘,了解它们是如何提供和分配服务的。

什么是 Provider

Provider 是 NestJS 中的一种核心构建块,它提供了封装与分享服务逻辑的方式。实际上,你可以将 Provider 看作是一种可以注入到任何地方的对象或实体。这些对象可以是类、工厂、值甚至更复杂的结构。不管它返回什么,它的核心意图是提供一种实现不同任务的方式,例如数据访问、辅助函数,所有这些都尽可能地可复用和可测试。

Providers 的主要类型

在 NestJS 中有五种主要的 Provider:

  • 值提供者
  • 类提供者
  • 工厂提供者
  • 异步工厂提供者
  • 别名提供者

以下内容,我们将详细深入探讨这五种类型的 Provider,并给出使用案例。

一、值提供者 Provider

值提供者是最直接的一种类型,它直接返回一个常量或者预定义的值。且更常见的用例是,将应用的配置注入到需要读取配置的服务中。

将配置对象作为值 Provider 的例子:

// 在模块定义中我们创建一个值 Provider
@Module({providers: [{provide: 'DATABASE_CONFIG',useValue: {host: 'localhost',port: 5432,user: 'dbuser',password: 'dbpassword',database: 'myDatabase'}}]
})// 在服务中,我们可以将这个值注入进来:
@Injectable()
export class DatabaseService {constructor(@Inject('DATABASE_CONFIG') private dbConfig: any) {}getConnectionDetails() {// 输出数据库配置信息console.log(this.dbConfig);}
}

二、类提供者 Provider

类提供者是 Provider 中常用的一种,它可以让我们通过依赖注入的方式来获取类的实例。这对复用和测试非常有价值,因为我们可以在测试时使用模拟的实例来替换真正的服务。

下面讲述了如何使用和注入类提供者的例子:

// 我们首先在模块定义中声明一个类提供者
@Module({providers: [ConfigService],
})// 接着在服务中,我们可以注入这个提供者
@Injectable()
export class UserService {constructor(private configService: ConfigService) {}getEnvironment() {// 输出当前应用环境console.log(this.configService.get('ENV'))}
}

三、工厂提供者 Provider

工厂提供者是最灵活的 Provider 形式。工厂函数可以返回任意值,并且可以用来执行复杂的同步或异步操作。同样的,这让我们可以根据运行时逻辑返回不同的结果或者根据不同的运行环境提供不同的实现。

下面是工厂提供者的一个例子:

// 在模块定义中,我们创建一个工厂提供者
@Module({providers: [{provide: 'ENV_CONFIG',useFactory: () => {// 例如,我们可以在此基于一些环境变量返回不同的配置:return process.env.NODE_ENV === 'development'? developmentConfig: productionConfig;},},],
})// 届时我们可以在服务中注入这个工厂提供者
@Injectable()
export class UserService {constructor(@Inject('ENV_CONFIG') private envConfig: any) {}getConfig() {// 输出当前的环境配置console.log(this.envConfig);}
}

四、异步工厂提供者 Provider

异步工厂提供者与工厂提供者在原则上是相似的,但它们返回一个 Promise 或 Observable。当 Promise 解析或者 Observable 发射出结果时,这个结果就会在应用中作为注入的值。这项特性对于需要进行异步操作来提供值的需求场景非常有用,比如数据库连接,远程配置等。

以下是异步工厂提供者的一个应用场景:

//在模块定义中我们先定义一个异步工厂提供者
@Module({providers: [{provide: 'DATABASE_CONNECTION',useFactory: async () => {const options = await getDbOptions();return createConnection(options);},},],
})// 在服务中,我们可以注入这个数据库连接
@Injectable()
export class UserService {constructor(@Inject('DATABASE_CONNECTION') private dbConnection: Connection) {}findUser(id: number) {return this.dbConnection.getRepository(User).findOne(id);}
}

在这个示例中,DATABASE_CONNECTION 是一个异步工厂提供者,这个提供者会异步地创建数据库连接。

五、别名提供者 Provider

别名提供者允许我们为提供者赋予别名,这样我们可以在不同上下文中引用并使用同样的值。这在某些需要多次引用同一个提供者或者希望使用更具语义化名称的场景中很有用。

下面是一个别名提供者的使用示例:

// 在模块定义中,我们创建 ConfigService 的别名
@Module({providers: [ConfigService,{provide: 'AppConfig',useExisting: ConfigService,},],
})// 在服务中,我们可以使用别名来注入这个提供者
@Injectable()
export class UserService {constructor(@Inject('AppConfig') private configService: ConfigService) {}getEnvironment() {// 输出当前应用环境console.log(this.configService.get('ENV'));}
}

在这个示例中,AppConfigConfigService 的别名,所以当我们请求 AppConfig 的时候,我们实际上获取到的是 ConfigService 的实例。

总结

本文介绍了 NestJS 中绝大多数的 provider 类型及其使用方式。希望这篇文章能帮助你理解不同的 provider 及其适用的场景。但我们这次的探索只是冰山一角,NestJS 还有很多高级特性等待你去挖掘。

这篇关于一篇文章学会如何使用 NestJS 的五种 Provider 提供者的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/564547

相关文章

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MyBatis ParameterHandler的具体使用

《MyBatisParameterHandler的具体使用》本文主要介绍了MyBatisParameterHandler的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、概述二、源码1 关键属性2.setParameters3.TypeHandler1.TypeHa

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完