模块
- 即具有
@module()
装饰器的类 -
@Module()
装饰器提供了元数据
,Nest.js用它来组织应用程序结构
- 模块之间的依赖关系,决定了应用程序树的结构
- 每个模块都有一组紧密相关的功能,根模块作为统一的模块树的根节点
模块的结构
@Module装饰器
接受一个描述模块属性的对象
。
-
providers
由Nest.js注入器实例化的提供者,即服务处理程序,可在整个模块中共享 -
controllers
控制器 -
import
为当前模块贡献provier
@module({
import: [UserOrgModule, TypeOrmModule.forFeature([User])],
providers: [AuthService],
controllers: [AuthController]
})
功能模块
CatsController和CatsService属于同一个应用程序域,因此放在同一个功能模块CatsModule下面。
//cats/cats.module.ts
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}
//通过cli方式创建module
$ nest g module cats
//有根模块ApplicationModule和CatsModule两个模块之后的典型的目录结构:
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
共享模块
实际上每一个模块都是共享模块
。即一旦创建就能被任意模块重复使用
。当需要在几个模块间共享实例CatsService
,需要把该实例放在exports
数组中。
这样每个导入CatsModule
的模块都可以访问CatsService
,且共享CatsService
实例。
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 {}
模块导出
模块不仅可以导出自身的Provider
,还可以再导出自己导入的模块
@Module({
imports: [CommonModule],
exports: [CommonModule],
})
export class CoreModule {}
依赖注入
-
Provider
可以注入到模块(即类)
中(如基于配置目的) -
模块/类
不能注入到Provider
中(循环依赖
)
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 readonly catsService: CatsService) {}
}
全局模块
- 当你希望使用某些可随处使用的东西(如,
helper
,数据库连接
等) - Nest将
Provider
封装在模块
内部,必须导入该模块
才能使用模块的Provider
此时,某些模块就应当成为全局模块:
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 装饰器
使模块成为全局作用域
(还是尽量使用imports数组
的方式使模块api透明)
动态模块 --- ???
- 可轻松创建
自定义模块
,这些模块可动态注册和配置Provider
//DatabaseModule的定义
import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';
@Module({
providers: [Connection], //默认情况下,Connection在@Module()装饰器元数据中定义Provider。
})
export class DatabaseModule {
static forRoot(entities = [], options?): DynamicModule {
const providers = createDatabaseProviders(options, entities);
return {
//global: true //在全局范围内注册动态模块
module: DatabaseModule,
providers: providers,
exports: providers,
};
}
}
-
forRoot()
可以同步或异步(Promise)返回动态模块
-
DynamicModule
返回的属性扩展
(而非覆盖)@Module装饰器
中定义的模块元数据
// 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 {}
//依次重新导出动态模块
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 {}