当前位置: 首页 > 后端技术 > Node.js

NestJs学习之旅(四)——模块系统

时间:2023-04-03 20:56:16 Node.js

欢迎继续关注NestJs之旅系列文章ModuleNestJs中的模块是构建和组织业务单元的基本要素。使用@Module()修饰模块来声明模块的元信息:本模块导出哪些服务提供者本模块提供哪些依赖模块每个NestJs至少有一个根模块,这个是app.module.ts定义的。根模块一般不包含具体的业务逻辑,具体的业务逻辑应该被淹没在各个子业务模块中。比如我们开发一个商城系统,系统有以下业务模块:订单中心、用户中心、支付中心、产品中心、物流中心,那么我们可以定义如下模块结构:|--app.module。ts|--顺序|--顺序。module.ts|--服务|--order.service.ts|--控制器|--order.controller.ts|--用户|--user.module.ts|--服务|--user.service。ts|--controllers|--user.controller.ts|--pay|--pay.module.ts|--services|--wepay.service.ts|--alipay.service.ts|--pay.service.ts|--controller|--pay.controller.ts...模块化有以下优点:低耦合业务边界清晰,容易排错,易于维护模块声明和配置@Module()修饰classes是模块类,装饰器的典型用法如下:@Module({providers:[UserService],controllers:[UserController],imports:[OrderModule],exports:[UserService]})exportclassUserModule{}参数名称描述providers服务提供者列表,该模块可用,可以自动注入到控制器列表中。该模块可用,用于绑定路由以访问该模块导入的模块。如果需要使用其他模块的服务提供者,则必须导入其他模块的导出。该模块导出。只有这里定义的服务提供者才能在其他模块中使用重新导出ts://a.tsexportinterfaceA{}//index.tsexport*from'./a';我们在使用的时候可以直接使用下面的代码,在NestJs中封装import{A}from'./index'modules方面也有类似的用法。比如我们定义了两个基本模块,使用的时候基本都是一起导入的。这个时候我们通过模块Re-export封装成一个CoreModule,直接从其他地方导入CoreModule@Module({providers:[CommonService],exports:[CommonService]})exportclassCommonModule{}@Module({providers:[Util],exports:[Util]})exportclassUtilModule{}@Module({imports:[CommonModule,UtilModule],exports:[CommonModule,UtilModule]})exportclassCoreModule{}模块初始化和依赖注入如果在模块实例化时需要运行一些逻辑,并且逻辑有外部依赖,可以通过以下方式处理:import{Module}from'@nestjs/common';import{UserController}from'./user.控制器';从'导入{UserService}。/user.service';@Module({controllers:[UserController],providers:[UserService],})exportclasscatsModule{constructor(privatereadonlyuserService:UserService){//没有@Inject//调用userService}}全局模块上面定义的模块都需要手动导入。如果有些模块使用率很高,比如工具模块,此时可以声明为全局模块。可以使用@Global()声明全局模块。从'@nestjs/common'导入{模块};从'./user.controller'导入{UserController};从'./user.service'导入{UserService};@Global()@Module({控制器:[UserController],providers:[UserService],})exportclasscatsModule{}动态模块都是上面定义的静态模块,如果我们需要动态声明我们的模块,比如数据库模块,我会在连接成功后才返回模块。这时候就需要使用动态模块来处理了。使用模块名.forRoot()方法返回模块定义,这种方式定义的模块是动态模块。@Module({providers:[DatabaseProvider]})exportclassDatabaseModule{staticasyncforRoot(env:string){constprovider=createDatabaseProvider(env);//根据环境变量连接不同的数据库return{module:DatabaseModule,providers:[provider],exports:[provider]}}}//user.module.ts@Module({imports:[DatabaseModule.forRoot('production')]})exportclassUserModule{}在生产环境中pose上有一个mall系统的模块示例,我们的业务模块在开发的时候需要注册到AppModule中,这样才能生效.这样也有一个好处,有点像插拔的例子。取消AppModule中的注册即可。@Module({imports:[UserModule,GoodsModule,OrderModule,PayModule]})exportclassAppModule{}端模块系统是NestJs的另一个重要特性。个人认为是基于DDD思想。每个模块都是一个独立的领域业务,可以由一个团队独立开发。可以同时开发多个模块。如果存在依赖问题,可以先暴露模块和对应的接口。别人正常调用你的接口。实现类开发完成后,NestJs会自动注入实现类。调用者的代码不要更改。如果觉得自己有所收获,请分享给更多有需要的朋友,谢谢!如果你想交流更多关于NestJs的知识,欢迎加入群讨论!