宁波网站建设的过程,河南省和城乡建设厅网站首页, 天堂资源帝,首服网页游戏开服表一、基础注入方式
1. 构造函数注入#xff08;Constructor Injection#xff09;
适用场景#xff1a;模块间依赖传递#xff0c;服务初始化时必须存在的依赖
实现方式#xff1a;通过构造函数参数声明依赖#xff0c;NestJS 自动解析并注入
Injectable()
class UserServ…一、基础注入方式
1. 构造函数注入Constructor Injection
适用场景模块间依赖传递服务初始化时必须存在的依赖
实现方式通过构造函数参数声明依赖NestJS 自动解析并注入
Injectable()
class UserService {constructor(private readonly logger: LoggerService) {} // 自动注入 LoggerServicegetUser() {this.logger.log(Fetching user data);// 业务逻辑}
}2. 属性注入Property Injection
适用场景可选依赖或动态注入场景
实现方式使用 Inject() 装饰器配合自定义 Token
Injectable()
class OrderService {Inject(PAYMENT_GATEWAY) // 自定义 Tokenprivate paymentGateway: PaymentService;processPayment() {this.paymentGateway.charge(); // 动态注入的支付网关}
}二、高级注入模式
3. 值提供者Value Provider
适用场景注入配置常量、第三方库实例
实现方式通过 useValue 定义固定值
Module({providers: [{provide: API_KEY,useValue: 12345-ABCDE, // 硬编码 API Key},{provide: EXTERNAL_SDK,useValue: new ThirdPartySDK(), // 注入第三方实例}]
})
class ConfigModule {}4. 类提供者Class Provider
适用场景根据环境动态切换实现类
实现方式使用 useClass 指定具体类
Module({providers: [{provide: ConfigService,useClass: process.env.NODE_ENV prod ? ProdConfigService : DevConfigService,}]
})
class AppModule {}5. 工厂提供者Factory Provider
适用场景需要运行时计算或组合依赖的场景
实现方式通过 useFactory 动态创建实例
Module({providers: [{provide: DatabaseConnection,useFactory: async (configService: ConfigService) {const config await configService.getDatabaseConfig();return createConnection(config);},inject: [ConfigService], // 注入其他依赖}]
})
class DatabaseModule {}6. 异步提供者Async Provider
适用场景处理异步初始化操作如数据库连接
实现方式结合 useFactory 与 async/await
Module({providers: [{provide: RedisClient,useFactory: async () {const client createClient({ url: redis://localhost:6379 });await client.connect();return client;},}]
})
class CacheModule {}7. 多提供者Multi Provider
适用场景插件系统、中间件集合等需要多个同类实现的场景
实现方式设置 multi: true 标记
Module({providers: [{provide: EventListeners,useClass: OrderListener,multi: true,},{provide: EventListeners,useClass: PaymentListener,multi: true,}]
})
class EventModule {}三、最佳实践与常见问题
1. 模块化设计原则
单一职责模块每个模块聚焦特定功能领域如 UserModule、AuthModule跨模块依赖通过 exports 暴露服务避免循环导入Module({providers: [UserService],exports: [UserService], // 其他模块可注入 UserService
})
class UserModule {}2. 测试优化策略
模拟依赖使用 nestjs/testing 创建隔离测试环境const module await Test.createTestingModule({providers: [UserService,{ provide: LoggerService, useValue: mockLogger },],
}).compile();3. 性能优化技巧
延迟加载对非关键依赖使用 LazyInject()需第三方库支持作用域控制通过 Injectable({ scope: Scope.TRANSIENT }) 管理实例生命周期
4. 常见问题解析
循环依赖使用 forwardRef() 打破循环Module({imports: [forwardRef(() OrderModule)],
})
class UserModule {}Token 冲突优先使用类名作为 Token避免字符串 Token 重复
四、实战案例TypeORM 集成
Module({imports: [TypeOrmModule.forRootAsync({useFactory: (config: ConfigService) ({type: postgres,url: config.get(DATABASE_URL),entities: [__dirname /**/*.entity{.ts,.js}],}),inject: [ConfigService],}),TypeOrmModule.forFeature([UserEntity]),],providers: [UserService],
})
class UserModule {}Injectable()
class UserService {constructor(InjectRepository(UserEntity)private userRepo: RepositoryUserEntity,) {}async findUser(id: string) {return this.userRepo.findOne(id);}
}五、总结
NestJS 的依赖注入系统通过多样化的注入方式和灵活的提供者配置为开发者提供了强大的架构设计能力。从基础的构造函数注入到复杂的工厂提供者每种模式都针对特定场景进行了优化。掌握这些模式后开发者可以
实现模块间低耦合设计提升代码可测试性与可维护性动态适配不同运行环境构建可扩展的插件化架构
建议在实际项目中结合具体场景选择注入方式并利用 NestJS 的模块化特性构建清晰的应用架构。