一篇文章学会如何使用 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构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

flask库中sessions.py的使用小结

《flask库中sessions.py的使用小结》在Flask中Session是一种用于在不同请求之间存储用户数据的机制,Session默认是基于客户端Cookie的,但数据会经过加密签名,防止篡改,... 目录1. Flask Session 的基本使用(1) 启用 Session(2) 存储和读取 Se