Nestjs实战超干货-概况-模块-Modules
模块
模块就是一个声明了装饰器@Module()的类。装饰器@Module()提供了元数据,以便让Nest组织应用程序结构。

每个应用程序至少有一个模块,即根模块。根模块是 Nest 用来构建应用程序图的起点,应用程序图是 Nest 用来解析模块和提供者关系和依赖关系的内部数据结构。虽然非常小的应用程序理论上可能只有根模块,但这不是典型情况。我们想强调的是,强烈建议将模块作为组织组件的有效方法。因此,对于大多数应用程序,生成的体系结构将使用多个模块,每个模块封装一组密切相关的功能。
@Module()装饰器采用单个对象,其属性描述如下:
providers | 由 Nest 注入器实例化的提供者,并且可以至少在整个模块中共享 |
controllers | 必须创建的一组控制器 |
imports | 导入模块的列表,这些模块导出了此模块中所需提供者 |
exports | 由本模块提供并应在其他模块中可用的提供者的子集。 |
默认情况下,模块封装providers。这意味着无法注入既不是当前模块的直接组成部分,也不是从导入的模块导出的providers。因此,您可以将模块中导出的providers视为模块的公共接口或 API。
功能模块
CatsController和CatsService属于同一应用程序域。由于它们密切相关,因此将它们移动到功能模块中是有意义的。功能模块只是组织与特定功能相关的代码,保持代码井井有条并建立清晰的边界。这有助于我们管理复杂性并使用 SOLID原则进行开发,尤其是随着应用程序或团队规模的增长的时候。
为了演示这一点,我们将创建CatsModule。
import { Module } from "@nestjs/common";
import { CatsController } from "./cats.controller";
import { CatsService } from "./cats.service";@Module({controllers: [CatsController],providers: [CatsService],
})
export class CatsModule {}
使用 CLI 创建模块,只需执行
$ nest g module cats命令即可。
以上,我们已经创建了cats.module.ts文件,并把与这个模块相关的所有东西都移到了cats目录下。我们需要做的最后一件事是将这个模块导入根模块 (根模块AppModule, 已经定义在app.module.ts文件内)。
import { Module } from "@nestjs/common";
import { CatsModule } from "./cats/cats.module";@Module({imports: [CatsModule],
})
export class AppModule {}
目录结构如下:
src
├──cats
│ ├──dto
│ │ └──create-cat.dto.ts
│ ├──interfaces
│ │ └──cat.interface.ts
│ ├─cats.service.ts
│ ├─cats.controller.ts
│ └──cats.module.ts
├──app.module.ts
└──main.ts
共享模块
在 Nest 中,默认情况下,模块是单例的,因此你可以轻松地在多个模块之间共享同一个提供者实例。

实际上,每个模块都是一个共享模块,一旦创建就能被任意模块重复使用。假设我们要在几个模块之间共享CatsService实例,则需要把CatsService放到模块CatsModule的exports数组中,如下所示:
import { Module } from "@nestjs/common";
import { CatsController } from "./cats.controller";
import { CatsService } from "./cats.service";@Module({controllers: [CatsController],providers: [CatsService],exports: [CatsService],
})
export class CatsModule {}
现在,任何导入CatsModule的模块都可以访问CatsService,并将与导入CatsModule的所有其他模块共享相同的实例。
模块重新导出
如上所示,模块可以导出其内部提供者程序。此外,他们可以重新导出导入的模块。在下面的示例中,CommonModule既可导入,又从CoreModule导出,使其可用于导入此模块的其他模块。
@Module({imports: [CommonModule],exports: [CommonModule],
})
export class CoreModule {}
依赖注入
模块类也可以注入提供者程序(例如,出于配置目的):
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';@Module({controllers: [CatsController],providers: [CatsService],
})
export class CatsModule {constructor(private catsService: CatsService) {}
}
但是,由于[循环依赖性],模块类不能注入到提供者中。
Global modules
如果您必须在任何地方导入同一组模块,则可能会变得乏味。与 Nest 不同,Angular提供者在全局范围内注册。定义后,它们随处可用。但是,Nest 将提供程序封装在模块范围内。如果不先导入封装模块,则无法在其他地方使用模块的提供程序。
当您想要提供一组开箱即用的提供程序(例如,帮助程序、数据库连接等)时,请使用@Global() 装饰器使模块全局化。
import { Module, Global } from "@nestjs/common";
import { CatsController } from "./cats.controller";
import { CatsService } from "./cats.service";@Global()
@Module({controllers: [CatsController],providers: [CatsService],exports: [CatsService],
})
export class CatsModule {}
@Global() 装饰器使模块全局可用。全局模块应仅注册一次,通常由根模块或核心模块注册。在上面的例子中,CatsService提供程序将无处不在,希望注入服务的模块不需要在其导入数组中导入CatsModule。
让所有的模块都成为全局模块不是一个好的设计决策。全局模块可用于减少必要的样板数量。
imports通常是使模块的 API 可供使用者使用的首选方式。
动态模块
Nest 模块系统包括一个强大的功能,称为动态模块。此功能使您能够轻松创建可动态注册和配置提供程序的可自定义模块。动态模块详细介绍[点这里(/fundamentals/dynamic-modules)]。在本章中,我们将简要概述以完成模块的介绍。
下面是DatabaseModule的动态模块定义示例:
import { Module, DynamicModule } from "@nestjs/common";
import { createDatabaseProviders } from "./database.providers";
import { Connection } from "./connection.provider";@Module({providers: [Connection],
})
export class DatabaseModule {static forRoot(entities = [], options?): DynamicModule {const providers = createDatabaseProviders(options, entities);return {module: DatabaseModule,providers: providers,exports: providers,};}
}
forRoot()方法可以同步或异步返回动态模块(即通过Promise)。
模块DatabaseModule在装饰器@Module()中定义了一个Connection的提供者,但是此模块的返回值还要看forRoot()方法,它返回了一系列的提供者,例如 repositories。所以,请注意动态模块的返回值是扩展了装饰器@Module()定义,而不是覆盖。所以模块DatabaseModule导出的providers,包含两部分,一部分是静态定义的Connection,另外一部分是forRoot()方法动态生成的 providers。
如果你想注册一个全局的动态模块,设置global=true即可。
{global: true,module: DatabaseModule,providers: providers,exports: providers,
}
使所有的模块都成为全局模块,不是一个好的设计策略。
可以通过以下方式导入和配置DatabaseModule:
import { Module } from "@nestjs/common";
import { DatabaseModule } from "./database/database.module";
import { User } from "./users/entities/user.entity";@Module({imports: [DatabaseModule.forRoot([User])],
})
export class AppModule {}
如果你想反过来重新导出动态模块,你可以在exports数组中省略forRoot()方法调用:
import { Module } from "@nestjs/common";
import { DatabaseModule } from "./database/database.module";
import { User } from "./users/entities/user.entity";@Module({imports: [DatabaseModule.forRoot([User])],exports: [DatabaseModule],
})
export class AppModule {}
动态模块一章更详细地介绍了本主题,并包含一个工作示例。
相关文章:
Nestjs实战超干货-概况-模块-Modules
模块 模块就是一个声明了装饰器Module()的类。装饰器Module()提供了元数据,以便让Nest组织应用程序结构。 每个应用程序至少有一个模块,即根模块。根模块是 Nest 用来构建应用程序图的起点,应用程序图是 Nest 用来解析模块和提供者关系和依赖…...
template
模板 模板注意事项 模板的函数体和声明一定要在一起,即放在同一个.h文件中,而不能将其分开到cpp和h文件中模板的编译技巧就是尽量多编译,模板很难查找错误模板的报错一般只有第一行有作用模板指定类型从左到右依次指定 模板推导 #pragma #…...
innovus中时序路径debug及命令使用详解?
写在前面:发现place结果所有与outport相关的timing check都找不到? 刚开始怀疑是sdc约束问题,check了input sdc文件及enc.dat/mmmc/mode/func.sdc 看一下是否设置了set_false_path.当然也可以用命令报出来: report_timing -unconstrained …...
C语言爱心代码大全集—会Ctrl+C就可以表白了
一、C语言爱心代码大全,会CtrlC就可以表白了! 博主整理了一个C语言爱心代码大全,里面有C语言爱心代码会动的动态效果和C语言爱心代码大全静态效果,只需复制粘贴就可以用啦! 1、动态C语言爱心代码效果图如下ÿ…...
python+vue+django耕地信息管理系统的设计与实现
基普通用户模块含有个人中心、耕地信息管理、转让许可申请管理、租赁许可申请管理等功能;普通管理员模块含有个人中心、用户管理、公示公告管理、耕地信息管理、耕地信息统计、转让许可申请管理、租赁许可申请管理、转让协议管理、租赁协议管理等功能;管…...
【云原生】Dockerfile制作WordPress镜像,实现compose编排部署
文章目录👹 关于作者前言环境准备目录结构dockerfile制作镜像yum 脚本Dockerfile-mariadb 镜像Dockerfile-service 镜像docker compose 编排提升✊ 最后👹 关于作者 大家好,我是秋意临。 😈 CSDN作者主页 😎 博客主页…...
五款好用又有趣的WIN10软件推荐
如果你想让你的电脑使用更方便、更有趣、更专业,那么你一定要看看这篇文章,因为我要给你推荐五款好用又有趣的WIN10软件 1.全局搜索——火柴 火柴是一款全局搜索软件,可以让你快速找到你想要的文件、程序、网页等,只需按下AltSp…...
朴素贝叶斯算法
# -*-coding:utf-8-*- """ Author: sunchang Desc: 代码4-7 朴素贝叶斯实现对异常账户检测 """ import numpy as np class NaiveBayesian: def __init__(self, alpha): self.classP dict() self.classP_f…...
【常见CSS扫盲雪碧图】从源码细看CSS雪碧图原理及实现,千字详解【附源码demo下载】
【写在前面】其实估计很多人都听过雪碧图,或者是CSS-Sprite,在很多门户网站就会经常有用到的,之所有引出雪碧图这个概念还得从前端加载多个图片时候页面闪了一下说起,这样给人的视觉效果体验很差,也就借此机会和大家说…...
Java多线程:ThreadLocal源码剖析
ThreadLocal源码剖析 ThreadLocal其实比较简单,因为类里就三个public方法:set(T value)、get()、remove()。先剖析源码清楚地知道ThreadLocal是干什么用的、再使用、最后总结,讲解ThreadLocal采取这样的思路。 三个理论基础 在剖析ThreadLo…...
96、数据的存储
运行实例: 在debug和release两种模式下,进行代码运行,debug下 i 的地址是大于arr[9] 的地址的,release 下i 的地址是小于arr[9] 的地址。原因是:release状态进行了优化处理。 C语言中基本的内置类型 整形数据类型 char …...
@EventListener注解详细使用(IT枫斗者)
EventListener注解详细使用 简介 EventListener是一种事件驱动编程在spring4.2的时候开始有的,早期可以实现ApplicationListener接口, 为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式;为的就是业务系统逻辑的解耦,提高…...
[c++17新增语言特性] --- [[nodiscard]]和[[maybe_unused]]
1 [[nodiscard]] 介绍和应用示例 [[nodiscard]] 是C++17引入的一个属性(Attribute),它用于向编译器提示一个函数的返回值应该被检查,避免其被忽略或误用。它可以被用于函数、结构体、类、枚举和 typedef 等声明上,表示如果函数返回值未被使用,或者结构体、类、枚举和 type…...
Centos7安装和使用docker的笔记
最近项目要求用容器部署,所以需要将docker的用法搞清楚,在操作过程中,积累了一些操作方法和技巧,作为笔记,为后面使用做个参考。 首先安装docker需要给centos增加源(参考https://www.runoob.com/docker/cen…...
结构像与功能像
导读现代神经成像技术使我们能够研究活体大脑的结构和功能。活体神经成像的益处是显而易见的,而且在基础和临床神经科学中,神经成像已经取得了巨大进展。本文概述了利用活体神经成像研究大脑结构和功能的工作和成就。介绍了几种不同类型的结构MRI成像方法…...
【IAR工程】STM8S基于ST标准库读取DS1302数据
【IAR工程】STM8S基于ST标准库读取DS1302数据✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创!🍁对于文中所提供的相关资源链接将作不定期更换。&…...
【SpringBoot】实现后端服务器发送QQ邮件验证码的功能
步骤一、添加邮件相关依赖二、配置邮件服务器三、发送邮件PS:SMTP 发送失败的解决方案一、添加邮件相关依赖 在 pom.xml 文件中添加 JavaMail 和 Spring Mail 相关的依赖。示例代码如下: <dependency><groupId>com.sun.mail</groupId&g…...
vue在input中输入后,按回车,提交数据
vue在input中输入后,按回车,提交数据 1.展示效果如下: 2.代码展示: <div><el-input v-model"toAddNameText" keyup.enter.native"toAddName()" placeholder"回车,即新增该竖杆名称…...
【YOLOX】用YOLOv5框架YOLOX
【YOLOX】用YOLOv5框架YOLOX一、新建common_x.py二、修改yolo.py三、新建yolox.yaml四、训练最近在跑YOLO主流框架的对比实验,发现了一个很奇怪的问题,就是同一个数据集,在不同YOLO框架下训练出的结果差距竟然大的离谱。我使用ultralytics公司…...
【python机器学习实验】——逻辑回归与感知机进行线性分类,附可视化结果!
【python机器学习实验】——逻辑回归与感知机进行线性分类,附可视化结果! 下载链接 下载链接 下载链接 可视化效果图: 感知机模型结果为例: 首先,我们有训练数据和测试数据,其每一行为(x,y,label)的形式…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...
