首页 > 其他分享 >Nestjs的Provider 和依赖注入

Nestjs的Provider 和依赖注入

时间:2023-12-16 18:01:19浏览次数:31  
标签:容器 依赖 DI 提供者 Nestjs 注册 Provider UserService


前言

上文介绍了如何理解依赖注入和控制反转,简单来说,控制反转是一种设计模式,可以将类与类的关系解耦,将人工维护转移给一个容器维护。要实现控制反转,依赖注入是一个常用方案,将依赖注册到 DI 容器中,哪里用到,就让容器将实例注入到哪里。

Nest 中的依赖注入,主要就是围绕提供者(Provider)展开。所谓的依赖,指的就是提供者类。本文通过一个简单示例,来演示 Nest 中的依赖注入是如何工作的(不涉及实现原理),主要分为三个步骤:

  1. 定义提供者
  2. 注册提供者
  3. 使用提供者

定义提供者

从代码上看,Nest 中的提供者 Provider,就是一个应用了 @Injectable() 装饰器的类,比如:

import { Injectable } from '@nestjs/common';

@Injectable() 
export class UserService { // UserService 类就是一个提供者
    findAllUsers() {
        // ......
    }
}

@Injectable() 装饰器的作用就是将提供者(比如这里的 UserService)作为依赖注册到 DI 容器中。之后当需要用到此提供者时,由 DI 容器负责完成实例化,并注入到需要的类中,从而将类与类之间的关系解耦。

注册提供者

上面只是定义了一个提供者,要使用提供者,还需要注册提供者。在一个模块定义中,比如 UserModule,在 @Module() 装饰器的 providers 属性中注册。

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';

@Module({
  providers: [UserService],
  controllers: [UserController]
})
export class UserModule {}

providers 属性是注册提供者的列表,Nest 注入器或者说是DI 容器会将这里的提供者进行实例化, 并且这些提供者在该模块内都是可共享的。

这里的 providers 其实是一种简写形式,完整的写法是:

providers: [
  {
    provide: UserService,
    useClass: UserService,
  },
];

provide 属性的值是一个标识符(inject token),DI 容器使用这个 token 来标识注册的提供者,在使用时也是根据此 token 来找到提供者。默认的话,如果只传了一个提供者的类,则 token 的值就是这个类。这一点很重要。

使用提供者

从提供者所发挥的作用上看,它就是能对外提供一些方法的类,供其他类使用。比如上面定义的 UserService,它的作用就是提供一些操作用户的逻辑,在 UserController 控制器类中使用:

import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';

@Controller('users')
export class UserController {
  constructor(private userService: UserService) {}

  @Get()
  async getAllUsers() {
    return this.userService.findAllUsers();
  }
}

上面的示例中,在 UserController 类中要使用 UserService 类中的方法,无需自己实例化,而是在构造函数中使用了一个类型标识:

constructor(private userService: UserService) {}

Nest 的 DI 容器就能根据 “UserService” 找到此依赖项,也就是在模块定义中注册的提供者 UserService 类,然后创建实例并返回给构造函数使用。这就是依赖注入,同时这也实现了 UserController 类和 UserService 类之间的解耦,交给由 DI 容器去维护。

总结

上述的过程,就是 Nest 中一个完整的依赖注入的过程,总结一下就是:

  • 使用 @Injectable() 装饰器将一个类定义为提供者
  • 在模块类中的 @Module() 中使用 providerss注册提供者
  • 在控制器中的构造函数中,通过注册提供者时的 token ,DI 容器将找到的提供者实例返回

如果有描述不准确之处,欢迎在评论区指出,感谢阅读。

标签:容器,依赖,DI,提供者,Nestjs,注册,Provider,UserService
From: https://blog.51cto.com/u_12382805/8853348

相关文章

  • Spring循环依赖
    Java中的循环依赖分两种:构造器的循环依赖:就是在构造器中有属性循环依赖,如下所示的两个类就属于构造器循环依赖@ServicepublicclassStudent{@AutowiredprivateTeacherteacher;publicStudent(Teacherteacher){System.out.println("Studenti......
  • springcloudalibabada搭建过程中springboot启动卡住起不来 (Started MoonceProviderApp
    如下图一样springcloudAlibaba在创建新模块之后启动新模块没有注册到nacos上,而是直接卡住起不来原因 原因是:引入了错误的web包: 解决办法:引入相应的 spring-boot-starter-web包:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot......
  • Nestjs 依赖注入和控制反转
    前言Nest.js是一个使用TypeScript实现的在Node.js环境中运行的Web服务开发框架。它借鉴了很多优秀的设计思想,本文来说一说Nest中的依赖注入和控制反转。依赖注入依赖注入,英文名是DependencyInjection,简称DI。什么是依赖注入?可以分开来看,就是“依赖”和“注入”。您可能......
  • 未能加载文件或程序集“Newtonsoft.Json”或它的某一个依赖项。找到的程序集清单定义
    原文链接:https://blog.csdn.net/weixin_45488182/article/details/132537085网上的资料,大都是因为版本号不一致,我检查了很多遍,我这边版本号是12.0.1与12.0.2,config里是12.0.0,应该算是一致的吧。并且清理重新生成后,就不会报这个错。程序可以正常运行了。今天终于解决了这个问题,......
  • 2023-12-14 npm和yarn无法拉取依赖,cnpm可以 ==》切换镜像源
    这两天遇到个问题,是关于依赖无法拉取的问题,尽管我有三分猜到了是什么原因,但我还是不肯往那个方向思考,哎,真是死牛一便颈。如,我要给前端项目装个express框架,用npm装,装了大半天一点反应都没有,用yarn装就直接报网络无法连接,如图: 用cnpm装就没问题,秒过。注意:我的电脑是能正常上网......
  • 【机器学习】算法作用与依赖库合集
    算法与库1.决策树:-库: fromsklearn.treeimportDecisionTreeClassifier(分类树) fromsklearn.treeimportDecisionTreeRegressor(回归树)-计算场景:分类和回归问题2.逻辑回归:-库: fromsklearn.linear_modelimportLogisticRegression-......
  • 使用yarn安装依赖包出现“There appears to be trouble with your network connection
    我们在使用yarn安装依赖包文件的时候,可能会出现“Thereappearstobetroublewithyournetworkconnection.Retrying...”超时的提醒,很有可能是因为yarn默认的镜像地址为国外,因此慢(超时)就说得过去了……1、......
  • vue项目 npm install 安装依赖 特别慢 解决办法
    vue项目npminstall安装依赖特别慢解决办法使用NPM(Node.js包管理工具)安装依赖时速度特别慢,为了安装Express,执行命令后两个多小时都没安装成功,最后只能取消安装,笔者20M带宽,应该不是我网络的原因,后来在网上找了好久才找到一种最佳解决办法,在安装时可以手动指定从哪个镜像服务器......
  • spring 怎么解决循环依赖的
    spring怎么解决循环依赖的理解spring的生命周期分为容器启动阶段、bean的实例化阶段、bean的属性注入阶段、bean的初始化阶段、bean的缓存阶段、bean的销毁阶段怎么解决循环依赖假设有两个对象X和Y,X依赖了Y,Y依赖了X,spring能解决循环依赖,底层主要接住了3个map。第一个是sing......
  • .NET 依赖注入的3中方式
    一、简介    依赖注入共有3种方式:构造函数注入、属性注入、方法注入二、构造函数注入    在program.cs中对组件进行注册:   builder.Services.AddScoped<IScopedService,ScopedService>();    服务注册配置后,在需要注入的类上使用构造函数。pu......