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

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.dtcms.com/a/339415.html

相关文章:

  • Hugging Face 核心组件介绍
  • 大功率变速箱总成双联试验台架系统参数
  • 机器人控制基础:运动控制中的串级pid原理以及实现方案(包含代码示例)
  • C/C++ 常见笔试题与陷阱详解
  • .net core web程序如何设置redis预热?
  • 【大白话解析】 OpenZeppelin 的 Address 库:Solidity安全地址交互工具箱​(附源代码)
  • Mybatis执行SQL流程(四)之MyBatis中JDK动态代理
  • Ansible 异步任务管理与内容重用详解
  • 10.Ansible角色管理
  • Ubuntu 和麒麟系统创建新用户 webapp、配置密码、赋予 sudo 权限并禁用 root 的 SSH 登录的详细
  • 网络间的通用语言TCP/IP-网络中的通用规则3
  • 缓存雪崩、缓存穿透、缓存击穿在实际中如何处理
  • Windows Git安装配置
  • PCL+Spigot服务器+python进行MC编程(使用Trae进行AI编程)---可以生成彩虹
  • 代码随想录Day56:图论(冗余连接、冗余连接II)
  • 【python】列表复制注意事项
  • 大模型+RPA:如何用AI实现企业流程自动化的“降本增效”?
  • 什么类型的项目会优先选择Headless CMS
  • 【habitat学习二】Habitat-Lab 快速入门指南(Quickstart)详解
  • 完美解决git报错拉取不到项目
  • 如何禁用 Windows 服务器的自动更新以避免意外重启
  • VMWare主机和客户机无法ping通
  • Android-ContentProvider的跨应用通信学习总结
  • Matplotlib数据可视化实战:Matplotlib安装与入门-跨平台环境配置与基本操作
  • 第四章:大模型(LLM)】07.Prompt工程-(2)Zero-shot Prompt
  • 【Linux】信号(二):Linux原生线程库相关接口
  • C#多线程学习—主子线程,Invoke与begininvoke
  • RabbitMQ:SpringBoot+RabbitMQ入门案例
  • 《用Proxy解构前端壁垒:跨框架状态共享库的从零到优之路》
  • vue3使用RouterLink跳转的时候,路径正确但是不显示对应内容