Nest 模块
基本概念
模块是带有@Module()装饰器的类。@Module()装饰器提供元数据,Nest使用这些元数据来组织应用程序的结构。
@Module()装饰器接受一个单一的对象作为参数,其属性描述了模块:
providers | 将由 Nest 注入器实例化并且至少可以在该模块中共享的提供程序享。 |
|---|---|
controllers | 此模块中定义的必须实例化的控制器集 |
imports | 导出此模块所需的提供程序的导入模块列表 |
exports | 这个模块提供的providers子集应该在引入此模块的其他模块中可用。您可以使用提供者本身,也可以只使用其标记(provide值)。 |
当我们使用nest g res User、nest g res Order 创建一个CURD模板的时候 nestjs 会通过imports自动帮我们引入模块
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { OrderModule } from './order/order.module';
@Module({
imports: [UserModule, OrderModule], // 导入模块集合
controllers: [AppController], // 注入控制器集合
providers: [AppService], // 注入服务集合
})
export class AppModule {}
共享模块
在user.module.ts里通过exports导出UserService服务
// user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
@Module({
controllers: [UserController],
providers: [UserService],
exports: [UserService],// 导出UserService服务
})
export class UserModule {}
// user.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class UserService {
getUserName() {
return 'Aiolimp';
}
}
此时在Order模块任何地方都可以共享UserService的服务了
在order.service.ts引入UserService,可以通过Inject或者构造函数注入UserService服务
// order.service.ts
import { Inject,Injectable } from '@nestjs/common';
import { UserService } from 'src/user/user.service';
@Injectable()
export class OrderService {
@Inject(UserService) // 依赖注入UserService服务
private readonly userService: UserService;
// constructor( private readonly userService: UserService){} //构造函数注入UserService服务
getOrderDesc():string {
let name = this.userService.getUserName()
return `Order获取到的用户名为:${name}`;
}
}
// order.controller.ts
import { Controller, Get } from '@nestjs/common';
import { OrderService } from './order.service';
@Controller('order')
export class OrderController {
constructor(private readonly orderService: OrderService) {}
@Get()
getOrderDesc() {
return this.orderService.getOrderDesc();
}
}
最后在浏览器访问http://localhost:3000/order
全局模块
使用**@Global**装饰器可以声明全局模块,此时无需在每个模块通过import重复声明
user.module.ts
import { Module,Global } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
@Global() // 全局模块,所有模块都可以使用UserService服务
@Module({
controllers: [UserController],
providers: [UserService],
exports: [UserService],// 导出UserService服务
})
export class UserModule {}
order.module.ts
import { Module } from '@nestjs/common';
import { OrderService } from './order.service';
import { OrderController } from './order.controller';
import { UserModule } from '../user/user.module';
@Module({
// UserModule注册成了全局模块,这里无需再导入
// imports: [UserModule],
controllers: [OrderController],
providers: [OrderService],
})
export class OrderModule {}
动态模块
动态模块主要就是为了给模块传递参数 可以给该模块添加一个静态方法 用来接受参数
使用forRoot在Nest中注册根模块,例如配置根模块的全局服务或者中间等
// config.module.ts
import { Module,DynamicModule } from '@nestjs/common';
interface Options {
path: string
}
@Module({})
export class ConfigModule {
static forRoot(options: Options): DynamicModule {
// 在此方法中根据需要创建模块
return {
module: ConfigModule,
providers: [
{
provide: 'CONFIG_OPTIONS', // 自定义服务提供者的名称
useValue: { baseApi: "/api" + options.path } // 提供的服务提供者的值,这里是一个数组,包含了要注入的实体类
}
], // 这里可以添加一些服务提供者,用于配置模块的功能
exports: [
{
provide: "Config",
useValue: { baseApi: "/api" + options.path }
}
]
};
}
}
app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { OrderModule } from './order/order.module';
import { ConfigModule } from './config/config.module';
@Module({
imports: [UserModule, OrderModule, ConfigModule.forRoot({path:'aiolimp'})], // 导入模块集合
controllers: [AppController], // 注入控制器集合
providers: [AppService], // 注入服务集合
})
export class AppModule {}