一篇文章学会如何使用 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

相关文章

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

Java中Map.Entry()含义及方法使用代码

《Java中Map.Entry()含义及方法使用代码》:本文主要介绍Java中Map.Entry()含义及方法使用的相关资料,Map.Entry是Java中Map的静态内部接口,用于表示键值对,其... 目录前言 Map.Entry作用核心方法常见使用场景1. 遍历 Map 的所有键值对2. 直接修改 Ma

MySQL 衍生表(Derived Tables)的使用

《MySQL衍生表(DerivedTables)的使用》本文主要介绍了MySQL衍生表(DerivedTables)的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学... 目录一、衍生表简介1.1 衍生表基本用法1.2 自定义列名1.3 衍生表的局限在SQL的查询语句select

Mybatis Plus Join使用方法示例详解

《MybatisPlusJoin使用方法示例详解》:本文主要介绍MybatisPlusJoin使用方法示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录1、pom文件2、yaml配置文件3、分页插件4、示例代码:5、测试代码6、和PageHelper结合6

MySQL分区表的具体使用

《MySQL分区表的具体使用》MySQL分区表通过规则将数据分至不同物理存储,提升管理与查询效率,本文主要介绍了MySQL分区表的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、分区的类型1. Range partition(范围分区)2. List partition(列表分区)3. H

使用SpringBoot整合Sharding Sphere实现数据脱敏的示例

《使用SpringBoot整合ShardingSphere实现数据脱敏的示例》ApacheShardingSphere数据脱敏模块,通过SQL拦截与改写实现敏感信息加密存储,解决手动处理繁琐及系统改... 目录痛点一:痛点二:脱敏配置Quick Start——Spring 显示配置:1.引入依赖2.创建脱敏

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件