首页 > 其他分享 >【NestJS系列】核心概念:Module模块

【NestJS系列】核心概念:Module模块

时间:2023-11-06 11:35:07浏览次数:35  
标签:info InfoService Module export NestJS 模块 import

前言

模块指的是使用@Module装饰器修饰的类,每个应用程序至少有一个模块,即根模块。根模块是Nest用于构建应用程序的起点,理论上Nest程序可能只有根模块,但在大多数情况下是存在多个模块的,每个模块各自封装一组相关的功能。

【NestJS系列】核心概念:Module模块_Node.js

@Module装饰器

@Module()装饰器可以传入一个对象,属性值如下:

providers

将由 Nest 注入器实例化的提供程序,并且至少可以在该模块中共享

controllers

该模块中定义的必须实例化的控制器集

imports

导入模块的列表,导出该模块所需的提供程序

exports

该子集providers由该模块提供,并且应该在导入该模块的其他模块中可用

@Module({
  imports: [NanjiuModule, UserModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

模块共享

如果你想把当前模块的service暴露给其它模块使用,则可以使用exports到处该服务

比如我使用nest g resource info新建了一个info类,并且使用export导出该服务

// info.module.ts
import { Module } from '@nestjs/common';
import { InfoService } from './info.service';
import { InfoController } from './info.controller';

@Module({
  controllers: [InfoController],
  providers: [InfoService], // 提供者
  exports: [InfoService] // 导出 InfoService 供其他模块使用
})
export class InfoModule {}

然后我在user模块中使用imports导入该模块

// user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { InfoModule } from 'src/info/info.module';

@Module({
  imports: [InfoModule], // 导入 InfoModule
  controllers: [UserController],
  providers: [UserService]
})
export class UserModule {}

最后在controller中依赖注入并使用

// user.controller.ts
import { InfoService } from 'src/info/info.service';

@Controller('user')
export class UserController {
  constructor(
    private readonly userService: UserService,
    private readonly infoService: InfoService, // 注入 InfoService
    ) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.infoService.findAll() // 调用 InfoService 的 findAll 方法

    // return this.userService.create(createUserDto);
  }
  //...
}

【NestJS系列】核心概念:Module模块_静态方法_02

这样就完成模块共享了,可以看到我们在user模块中可以调用info的服务

模块再导出

可以把一些常用的,公共的模块,全部先import进一个CommonModule,然后再把它们从exprots全部导出,以后如果有那个模块想要使用其中某个模块的Service,只需要将这个CommonModule导入即可,不用再导入所有的依赖模块

// common.module.ts
@Module({
  imports: [Module1, Module2, Module3, Module4],
  exports: [Module1, Module2, Module3, Module4],
})
export class CommonModule {}

依赖注入

模块类也可以注入provider服务

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

全局模块

通过@Global()装饰器声明一个全局模块,只需要在根模块imports注册该全局模块,就可以在其他所有模块内使用它导出的Service

比如:将info声明为全局模块

// info.module.ts
@Global() // 全局模块
@Module({
  controllers: [InfoController],
  providers: [InfoService], // 提供者
  exports: [InfoService] // 导出 InfoService 供其他模块使用
})
export class InfoModule {}

然后在user模块中无需导入,只需依赖注入就可直接使用(前提是已在根模块导入)

// user.controller.ts
import { CreateUserDto } from './dto/create-user.dto';
import { InfoService } from 'src/info/info.service';

@Controller('user')
export class UserController {
  constructor(
    private readonly userService: UserService,
    private readonly infoService: InfoService, // 注入 InfoService
    ) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.infoService.findAll() // 调用 InfoService 的 findAll 方法
  }
}

【NestJS系列】核心概念:Module模块_静态方法_03

动态模块

动态模块能够让我们创建可定制的模块,当导入模块并向其传入某些选项参数,这个模块根据这些选项参数来动态的创建不同特性的模块。

创建动态模块

动态模块其实就是给当前Module类提供一个forRoot方法,该方法返回一个新的Module,这个Module的类型是一个DynamicModule,在其他模块需要注册使用时,可以使用xxxModule.forRoot(args)来动态的注册不同的Module,以达到提供不同providers的目的。

这里我们创建一个config的动态模块

// config.module.ts
import { Module, DynamicModule, Global } from '@nestjs/common';
import { NanjiuService } from 'src/nanjiu/nanjiu.service';
import { UserService } from 'src/user/user.service';

interface Options {
    name: string
}
@Global()
@Module({
})
export class ConfigModule {
    static forRoot(options: Options): DynamicModule {
        console.log('options', options)
        return {
            module: ConfigModule,
            providers: [
                {provide: 'config', useClass: options.name === 'nanjiu' ? NanjiuService : UserService},
            ],
            exports: [
                {provide: 'config', useClass: options.name === 'nanjiu' ? NanjiuService : UserService}
            ]
        }
    }
}

这个例子很简单,首先需要自己编写一个静态方法,该方法通过接收传递进来的参数判断使用哪一个service,并且为了方便,我这里直接使用@Global()装饰器将该模块声明称了全局模块

传递参数使用

调用静态方法传递参数

// app.module.ts
@Module({
  imports: [ConfigModule.forRoot({name: 'fe'})],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

然后在controller中使用

import { Controller, Get, Inject } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService, 
    @Inject('config') private readonly configService // 注入 ConfigService
    ) {}

  @Get('/hello2')
  get2() {
    return this.configService.getHello() // 调用 ConfigService 的 getHello 方法
  }
}

比如上面forRoot传递的参数是{name: 'nanjiu'},所以此时的ConfigModule注入的应该是UserService

【NestJS系列】核心概念:Module模块_Node.js_04

修改forRoot参数

// app.module.ts
@Module({
  imports: [ConfigModule.forRoot({name: 'nanjiu'})],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

此时通过get方式再访问同样的路由,应该是访问到NanjiuService提供的服务了。

【NestJS系列】核心概念:Module模块_静态方法_05

以上就是动态模块的简单用法,后续内容我们还会再遇到它~

标签:info,InfoService,Module,export,NestJS,模块,import
From: https://blog.51cto.com/u_13756259/8202962

相关文章

  • Python模块之 traceback
    模块作用简介:使用Python中traceback模块来进行处理可以直观异常信息必要操作:>>>importtraceback安装:python内置函数,无需安装导入包:>>>importtraceback帮助查看:>>>help(traceback)方法(函数):>>>参数返回值返回True,否则返回False。......
  • Python模块之 pandas
    模块作用简介:1、PythonDataAnalysisLibrary或pandas是基于NumPy的一种工具,该工具是为了解决数据分析任务而创建的。Pandas纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会......
  • 关于 JavaScript 模块化的描述
    AMD是RequireJS在推广过程中对模块定义的规范化产出,而CMD是SeaJS在推广过程中对模块定义的规范化产出,也就是,RequireJS遵循AMD规范,而Sea.js遵循CMD规范eaJs遵循CMD规范为通用模块规范,RequireJs遵循AMD规范为异步模块规范。CMD依赖就近,AMD依赖前置。//CMDCommonModuleD......
  • 手撕Vuex-模块化共享数据下
    前言好,经过上一篇的介绍,了解了Vuex当中的模块化,本章主要介绍Vuex当中的模块化共享数据下篇。我们知道在全局的Store对象当中,我们可以定义全局的数据,那么如果我们在模块当中也定义了一个属性名称和全局的属性名称相同,那么会发生什么呢?我们先来看看,在全局当中定义了一个gl......
  • Idea中如何在一个项目中引入其他子模块?
    首先在Settings打开ProjectStructure,然后找到Modules,点击加号点击importmodule,将需要引进的module引进来。然后点击Artifacts可以看到比如说day22...这个是我现在的项目,day16是我需要引入的。那么就在红色横线上面右键点第一个。然后重新Rebuild一下整个项目就行了。......
  • 【django框架】共4大模块50页md学习文档 第3篇:django路由和网络请求使用详解
    当你考虑开发现代化、高效且可扩展的网站和Web应用时,Django是一个强大的选择。Django是一个流行的开源PythonWeb框架,它提供了一个坚实的基础,帮助开发者快速构建功能丰富且高度定制的Web应用全套Django笔记直接地址:请移步这里共10章,31子模块,总计2w余字路由配置学习目......
  • 【python进阶】14大模块200页知识体系md笔记,第4篇:linux命令进阶(2)
    本文从14大模块展示了python高级用的应用。分别有Linux命令,多任务编程、网络编程、Http协议和静态Web编程、html+css、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。完整版笔记直接地址:请移步这里共14......
  • UE4中的GamePlay模块
    链接该文档主要通过学习自己构建文件,形成GamePlay模块。下图是利用引擎创建的一个空模板C++代码结构简要流程UBT虚幻编译工具(UBT:UnrealBuildTool)是一个自定义工具,负责管理通过各种编译配置来编译虚幻引擎4(UE4)源代码的过程。该工具处理所有复杂的项目编译工作,编译UE4的......
  • tkinter模块
    以下内容参考的是:PythonGUI开发手册(化学工业出版社)一、创建一个空白窗口:fromtkinterimport*win=Tk()win.title("MyGUI")win.mainloop()二、设置窗口属性:1、设置窗口样式的相关方法及其含义:title()geoemetry("widthxheight") 设置窗口标题maxsize() ......
  • Python之openpyxl模块的学习
    简介之前针对Excel的读取都是使用的xlrd模块,但是在一次实践中发现xlrd模块去掉了对xlsx格式的支持,因此改用openpyxl。以下内容仅包含使用openpyxl读取Excel文档的操作,并且比较浅显,更多内容请参考官方文档。注:一个excel就是一个工作簿(workbook),一个工作簿含有多个工作表(sheet)实......