当前位置: 首页 > web >正文

NestJS @Inject 装饰器入门教程

一、核心概念解析

1.1 依赖注入(DI)的本质

依赖注入是一种设计模式,通过 IoC(控制反转)容器管理对象生命周期。在 NestJS 中,@Injectable() 标记的类会被容器管理,而 @Inject() 用于显式指定依赖项。

1.2 @Injectable() vs @Inject()

  • @Injectable():标记类为可注入的提供者(Provider),告知 NestJS 容器需要管理该类的实例。
  • @Inject(token):显式指定依赖项的注入令牌(Token),用于非类型安全的注入场景。

二、基础用法

2.1 构造函数注入(推荐)

// service.ts
import { Injectable } from '@nestjs/common';@Injectable()
export class LoggerService {log(message: string) {console.log(`[Logger] ${message}`);}
}// user.service.ts
import { Injectable, Inject } from '@nestjs/common';
import { LoggerService } from './logger.service';@Injectable()
export class UserService {// 自动解析 LoggerService 类型constructor(private readonly logger: LoggerService) {}getUser() {this.logger.log('Fetching user...');return { id: 1, name: 'John' };}
}

2.2 属性注入(特殊场景)

import { Injectable, Inject } from '@nestjs/common';@Injectable()
export class HttpService<T> {@Inject('HTTP_OPTIONS') // 显式指定令牌private readonly httpClient: T;
}

三、高级用法:自定义提供者

3.1 值提供者(Value Provider)

// app.module.ts
import { Module } from '@nestjs/common';@Module({providers: [{provide: 'API_KEY', // 自定义令牌useValue: '12345-ABCDE', // 静态值},],
})
export class AppModule {}// 使用场景
@Injectable()
export class ConfigService {@Inject('API_KEY') private readonly apiKey: string;
}

3.2 工厂提供者(Factory Provider)

// app.module.ts
import { Module } from '@nestjs/common';@Module({providers: [{provide: 'DATABASE_CONNECTION',useFactory: async () => {const config = await getConfig(); // 异步操作return new DatabaseConnection(config);},inject: [ConfigService], // 注入其他依赖},],
})
export class AppModule {}

3.3 类提供者(Class Provider)

// app.module.ts
import { Module } from '@nestjs/common';
import { CacheService } from './cache.service';@Module({providers: [{provide: 'CACHE_MANAGER',useClass: CacheService, // 指定具体类},],
})
export class AppModule {}

四、常见问题

4.1 依赖未解析错误

错误Nest can't resolve dependencies of the UserService (?)
原因:依赖项未在模块的 providers 中注册。
解决方案

@Module({providers: [UserService, LoggerService], // 确保所有依赖已注册
})
export class UserModule {}

4.2 循环依赖

场景ServiceA 依赖 ServiceB,同时 ServiceB 依赖 ServiceA
解决方案:使用 forwardRef 结合 @Inject

// service-a.ts
import { forwardRef, Inject } from '@nestjs/common';@Injectable()
export class ServiceA {constructor(@Inject(forwardRef(() => ServiceB)) private serviceB: ServiceB) {}
}// service-b.ts
import { forwardRef, Inject } from '@nestjs/common';@Injectable()
export class ServiceB {constructor(@Inject(forwardRef(() => ServiceA)) private serviceA: ServiceA) {}
}

五、最佳实践

  1. 优先构造函数注入:明确依赖关系,提升代码可读性。
  2. 避免滥用 @Inject:仅在非类型安全场景(如字符串令牌)时使用。
  3. 模块化设计:通过 providers 数组集中管理依赖,便于维护。
  4. 合理使用自定义提供者:解耦配置与业务逻辑,提升灵活性。

六、总结

@Inject 是 NestJS 依赖注入系统的关键工具,通过显式指定依赖令牌,解决了非类型安全场景下的注入问题。结合 @Injectable 和自定义提供者,可以构建出高可维护、松耦合的后端应用。

http://www.xdnf.cn/news/18355.html

相关文章:

  • Go语言中的优雅并发控制:通道信号量模式详解
  • MVC、MVP、MVCC 和 MVI 架构的介绍及区别对比
  • 决策树二-泰坦尼克号幸存者
  • Unity常用工具及默认快捷键
  • 视觉测试:确保应用界面一致性
  • 牛客面经 - 2025/8/19
  • 深入理解Redis持久化:让你的数据永不丢失
  • Android Studio常用知识总结
  • 技术攻坚全链铸盾 锁定12月济南第26届食品农产品安全高峰论坛
  • 上网行为管理-内容审计
  • 效果图只是起点:深挖3D可视化在家装建筑中的隐藏金矿
  • Leetcode 3654. Minimum Sum After Divisible Sum Deletions
  • DL00291-联邦学习以去中心化锂离子电池健康预测模型完整实现
  • el-input 重写带图标密码框(点击小眼睛显示、隐藏密码)
  • 当MySQL的int不够用了
  • 【教程】在 VMware Windows 虚拟机中使用 WinPE 进行离线密码重置或取证操作
  • 玛雅预言的技术性解构:历法算法、量子共振与文明预警机制
  • mongodb学习
  • Rust 入门 返回值和错误处理 (二十)
  • 编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET... 拒绝访问
  • 跟踪不稳定目标:基于外观引导的运动建模实现无人机视频中的鲁棒多目标跟踪
  • GeoTools 读取影像元数据
  • OpenHarmony 之多模态输入子系统源码深度架构解析
  • Web3.0 时代的电商系统:区块链如何解决信任与溯源问题?
  • SWMM排水管网水力、水质建模及在海绵与水环境中的应用
  • C++常见面试题-2.C++类相关
  • EPM240T100I5N Altera FPGA MAX II CPLD
  • 深度学习-167-MCP技术之工具函数的设计及注册到MCP服务器的两种方式
  • TensorFlow 面试题及详细答案 120道(11-20)-- 操作与数据处理
  • 【Linux】文件系统