nest.js的动态模块核心逻辑

动态模块的独立性

动态模块是通过静态模块的静态方法返回的,每次调用生成的模块实例是新的模块,它具有自己的模块作用域,它与原来的静态模块相比是独立两个模块

这类似于静态模块是基类,然后动态模块继承于它,创建一个新的类,多个动态模块之间也是独立的,相当于创建的多个实例。

所以无法通过静态模块直接去访问动态模块的提供者,但是可以使用有一个module 属性,就是用于在宿主模块中合并动态模块的提供者和导出项。

模块的作用域

在nest中,你可以把模块理解成js的文件模块,你要使用某个模块的方法,就必须导入这个方法所属的模块,并不存在什么父子层级关系。

有人错误的理解成子模块和父模块,认为导入的是子模块,子模块中再导入的又是孙子模块,父模块可以访问孙子模块,其实这是错误的。

需要明确一点,模块之前要访问彼此的提供者,只有两种方式:导入模块和全局模块,且提供者必须是导出的。

动态模块与自身静态模块类的关系

每个 DynamicModule 的返回值中包含一个 module 属性,它指定了模块的标识。这通常是静态模块类的名字,例如 MyDynamicModule。Nest.js 使用这个类名来识别模块是否相同。

typescript 复制代码
class MyDynamicModule {
   static register(config: any): DynamicModule {
       return {
           module: MyDynamicModule, // 静态模块的类名作为标识
           providers: [{ provide: 'CONFIG', useValue: config }],
           exports: ['CONFIG'],
       };
   }
}

使用register每次生成的都是新的动态模块,而这些动态模块的module属性都是MyDynamicModule类。 这样产生的效果是:

  1. 相同 module 标识的模块会共享静态模块的提供者
  2. 相同 module 标识的模块,它们会被认为是同一个模块,但是不是静态模块,而是静态模块的另外的一个分身
  3. 虽然 module 标识是静态模块类,但是静态模块无法访问动态模块生成的提供者,因为他们只是公用基类而创建的不同模块

我们将注册动态模块的那个模块称为动态模块的宿主模块:

typescript 复制代码
@Module({
  imports: [
    MyDynamicModule.register({ key: 'value1' }), // 动态模块
    MyDynamicModule.register({ key: 'value2' }), // 新的动态模块实例
  ],
})
export class AppModule {}

AppModule是MyDynamicModule生成的两个动态模块的宿主模块

这些动态模块的提供者只能在宿主模块中被访问,如果想让这些动态模块的提供者可以被外界访问,必须将动态模块导出。

typescript 复制代码
@Module({
  imports: [
    MyDynamicModule.register({ key: 'value1' }), // 动态模块
    MyDynamicModule.register({ key: 'value2' }), // 新的动态模块实例
  ],
  exports: [MyDynamicModule],
})
export class AppModule {}

这里为什么导出静态模块类,就能实现当前动态模块的导出呢?

其实是因为当前两个动态模块的module一样,都使用MyDynamicModule作为模块的命名空间,所以会合并两个动态模块的 providersexports 到同一个模块中,并且模块的命名空间是类MyDynamicModule,类MyDynamicModule只是作为一个标识符,让两个动态模块的内容合并,导出的是当前宿主模块中以类MyDynamicModule为标识符合并的动态模块,与静态MyDynamicModule其实关系不大。

相关推荐
狂炫冰美式6 小时前
人均配了AI, 为什么公司还是没变快? 🤔 本质还是分布式系统问题
前端·后端·架构
她的男孩8 小时前
Spring Boot 接 Flowable 工作流:用 3 个注解搭一个请假审批流程
java·后端·架构
爱读源码的大都督8 小时前
Claude Code源码分析(三):为什么系统提示词中需要有tools呢?
前端·人工智能·后端
爱勇宝8 小时前
Claude Code 被曝暗藏“隐形检测”代码:封代理不是最可怕的,可怕的是你根本不知道它在干什么
前端·后端·程序员
ITOM运维行者8 小时前
从零搭建企业级服务器监控体系:踩坑实录与架构设计
前端·后端
用户4099322502128 小时前
Vue状态管理入门第四章:组合式store和SSR风险
前端·vue.js·后端
用户34232323763178 小时前
SPI 通信与高速外设驱动详解
后端
魏祖潇9 小时前
SDD 完整指南——Spec 端打底、Story 端交付、留白区
人工智能·后端
feelmylife599 小时前
消息队列可靠投递与幂等消费 -- 从"消息丢了"到"消息别重复"的完整工程实践
后端
雪隐9 小时前
个人电脑玩AI-10让5060 Ti给你打工——部署 Odysseus:终于有个能打的"AI管家"了
人工智能·后端