NestJS 入门(2):依赖注入到底解决了什么问题?
上一篇NestJS 入门先搞懂 Module、Controller、Service 讲了 Module / Controller / Service 三件套。学完之后很多人会卡在同一个问题上Controller 里明明没有new AuthService()为什么还能直接用this.authService答案就是依赖注入Dependency Injection简称 DI。这篇文章只讲清楚一件事Nest 如何帮你创建对象、并把它们接到一起。1. 先看「不用 DI」会怎样如果手写 Express 风格登录接口大概会变成这样// 伪代码自己 new 的世界constjwtServicenewJwtService({secret:...});constprismanewPrismaService();constauthServicenewAuthService(jwtService,prisma);constauthControllernewAuthController(authService);问题很快出现谁负责创建谁依赖一多手动组装会变成一棵大树。换实现很难。测试时想换成假的JwtService到处都要改new。容易重复创建。多个地方各自new PrismaService()数据库连接、配置就可能不一致。Nest 的做法是你只声明「我需要什么」创建和接线交给框架。2. 最常见写法构造函数注入认证 Controller 是这样写的Controller(api/auth)exportclassAuthController{constructor(privatereadonlyauthService:AuthService){}Post(login)login(Body()body:{email:string;password:string}){returnthis.authService.login(body.email,body.password);}}关键就一行constructor(privatereadonlyauthService:AuthService){}含义是「创建AuthController时请给我一个AuthService实例。」你不用关心AuthService什么时候被new它内部还依赖了谁全项目是不是共用同一个实例默认情况下Nest Provider 是单例Service 自己也可以继续注入依赖。认证 Service 里同时需要 JWT 能力和数据库能力Injectable()exportclassAuthService{constructor(privatereadonlyjwtService:JwtService,privatereadonlyprisma:PrismaService){}privateasyncgenerateTokens(user:User){constpayload{sub:user.id,email:user.email,name:user.name};constaccessTokenthis.jwtService.sign(payload,{expiresIn:30m,});constrefreshTokenthis.jwtService.sign(payload,{expiresIn:7d,});return{accessToken,refreshToken};}}于是依赖链变成AuthController └── 需要 AuthService ├── 需要 JwtService └── 需要 PrismaService你只在构造函数里「点名」Nest 负责把整条链拼好。3.Injectable()告诉 Nest「我可以被注入」Service、Guard、Strategy 这些类通常会加上Injectable()exportclassAuthService{/* ... */}Injectable()exportclassJwtAuthGuardextendsAuthGuard(jwt){}Injectable()exportclassJwtStrategyextendsPassportStrategy(Strategy){// ...}可以把它理解成一张标签这个类不是普通工具函数它是可以被容器管理、可以被注入的 Provider。没有这张标签、又没在 Module 里正确注册时Nest 往往就不知道该怎么创建它。4. Module 才是「注册表」光写constructor(private readonly authService: AuthService)还不够。Nest 还要在某个 Module 里看到这个类已经登记过了。Module({imports:[PrismaModule,PassportModule,JwtModule.register({secret:process.env.JWT_SECRET||your-secret-key,signOptions:{expiresIn:30m},}),],controllers:[AuthController],providers:[AuthService,JwtStrategy,JwtAuthGuard],exports:[AuthService,JwtAuthGuard],})exportclassAuthModule{}把这四块对应到 DI字段和依赖注入的关系providers本模块「能提供」哪些可注入对象controllers也由 Nest 创建构造函数里的依赖从容器取imports引入别的模块已经 export 出来的能力exports把本模块的 Provider 分享给其他模块所以 DI 不是魔法流程其实很明确在 Module 里注册 Provider在构造函数里声明类型依赖Nest 启动时解析依赖图并创建实例请求进来时直接用已经接好线的对象5. 跨模块共享exportsimports文档模块要用到项目相关能力时不是直接去new ProjectsService()而是Module({imports:[PrismaModule,ProjectsModule],controllers:[DocumentsController],providers:[DocumentsService],exports:[DocumentsService],})exportclassDocumentsModule{}DocumentsService构造函数里注入别人的 ServiceInjectable()exportclassDocumentsService{constructor(privatereadonlyprojectsService:ProjectsService,privatereadonlyprisma:PrismaService){}}规则很简单A 模块要用 B 模块的 ServiceB 必须先exports它A 再importsB 模块少任何一步运行时都会报「Nest can’t resolve dependencies」这类错误。初学时遇到这个报错优先检查有没有注册、有没有 export、有没有 import。6. 全局模块减少到处imports数据库这类「几乎处处都要用」的能力可以做成全局模块import{Global,Module}fromnestjs/common;import{PrismaService}from./prisma.service;Global()Module({providers:[PrismaService],exports:[PrismaService],})exportclassPrismaModule{}Global()的含义是只要根模块引入一次其他模块通常不必再重复imports: [PrismaModule]也能注入PrismaService。适合基础设施数据库、日志、配置。业务模块不建议随便全局化否则模块边界会变糊。7. 一张图看懂「谁创建了谁」以登录接口为例启动阶段Nest 容器装配 AuthModule 注册 AuthController / AuthService / JwtAuthGuard ... JwtModule 提供 JwtService PrismaModule 提供 PrismaService Nest 创建 PrismaService JwtService AuthService(jwtService, prisma) AuthController(authService) 请求阶段 POST /api/auth/login → AuthController.login() → AuthService.login() → JwtService.sign() 签发 token对比手动new你只声明依赖关系创建顺序、单例管理、跨模块共享由容器处理这就是 DI 的核心价值把「对象怎么创建」从业务代码里拿走。8. 为什么测试也更轻松直觉版有了构造函数注入测试时可以塞假依赖而不用改业务代码结构// 伪代码测试时替换依赖constfakeJwt{sign:()fake-token,verify:()({sub:1})};constauthServicenewAuthService(fakeJwtasany,fakePrismaasany);真正项目里还会用 Nest 的测试工具去覆盖整个 Module。入门阶段先记住结论即可依赖从外面传入而不是在类内部写死new替换起来才容易。9. 进阶一瞥循环依赖真实项目里有时会出现DocumentsService依赖ProjectsServiceProjectsService又依赖DocumentsService两边互相要对方Nest 解析依赖图时会卡住。这时会看到forwardRef()imports:[forwardRef(()ProjectsModule)]以及构造函数里的Inject(forwardRef(()DocumentsService))privatereadonlydocumentsService:DocumentsService入门阶段不必深挖。先会用「单向依赖 exports/imports」就够了真遇到循环依赖再回头查forwardRef。10. 小结依赖注入解决的是谁来创建对象、如何把依赖接上。最常用写法constructor(private readonly xxx: XxxService)Injectable()标记可注入类Module 的providers/imports/exports决定能否被解析跨模块共享靠exportsimports基础设施可用Global()报错「can’t resolve dependencies」时先查注册与导出再查依赖方向对照上一篇的三问现在可以多问第四句哪个 Controller 接请求哪个 Service 做业务哪个 Module 组装它们这个 Service 的依赖是从哪里注入进来的下一篇可以讲Guard 如何挡住未登录请求——把UseGuards(JwtAuthGuard)从「装饰器」讲成「请求链路里的一道门」。系列导航上一篇NestJS 入门先搞懂 Module、Controller、Service

相关新闻

OpenUtau:如何用开源虚拟歌手软件创作专业级音乐作品?[特殊字符]

OpenUtau:如何用开源虚拟歌手软件创作专业级音乐作品?[特殊字符]

OpenUtau:如何用开源虚拟歌手软件创作专业级音乐作品?🎵 【免费下载链接】OpenUtau Open singing synthesis platform / Open source UTAU successor 项目地址: https://gitcode.com/gh_mirrors/op/OpenUtau 你是否曾梦想创作属于自己…

2026/8/11 7:13:19 阅读更多 →
机器学习工程化与可复现实验流程设计:升级前先做这几项确认

机器学习工程化与可复现实验流程设计:升级前先做这几项确认

机器学习工程化与可复现实验流程设计:升级前先做这几项确认范围说明: 本文的升级路径为演练;可复现性应由依赖锁定、数据版本和运行记录证明。锁定 Python 包版本并不能保证运行环境完全一致:驱动、CUDA runtime、C ABI 和自定义扩…

2026/8/11 5:22:01 阅读更多 →
MySQL外键约束详解:原理、应用与优化

MySQL外键约束详解:原理、应用与优化

1. 外键基础概念与核心价值外键(Foreign Key)是关系型数据库中实现表间关联的核心机制。作为从业15年的DBA,我处理过上千个外键相关的案例,深刻理解它在数据完整性维护中的不可替代性。简单来说,外键就是一个表中的字段…

2026/8/11 6:40:41 阅读更多 →

最新新闻

2026岳阳危房鉴定检测怎么选?老旧房危房鉴定靠谱机构 TOP 结构安全检测+ 报告可查 电话汇总

2026岳阳危房鉴定检测怎么选?老旧房危房鉴定靠谱机构 TOP 结构安全检测+ 报告可查 电话汇总

岳阳老城区街巷深处,不少老旧小区楼体斑驳、墙体开裂,乡镇自建房因年久失修隐患暗藏,厂房商铺经营者、学校医院管理者纷纷将危房安全评估提上日程。然而市面上危房鉴定机构鱼龙混杂,部分无资质团队出具的报告根本无法通过住建审核…

2026/8/11 15:51:57 阅读更多 →
5G与6G:下一代移动通信

5G与6G:下一代移动通信

【814】5G与6G:下一代移动通信 你有没有这种感觉: 4G刚用熟,5G就来了? 5G还没全覆盖,6G又在路上了? 移动通信的迭代速度,比换手机还快。 从1G到5G 移动通信演进: ┌──────────────────────────────────────────────…

2026/8/11 15:51:57 阅读更多 →
CY7-PEG-NHS 花菁近红外荧光偶联试剂:产品特性说明

CY7-PEG-NHS 花菁近红外荧光偶联试剂:产品特性说明

CY7‑PEG‑NHS 属于近红外花菁 CY7 染料修饰 PEG 末端 NHS 活性酯的荧光偶联中间体,同时具备近红外荧光信号、PEG 亲水增稳效应与 NHS 氨基反应活性三大特性,可实现蛋白、多肽及高分子载体的荧光标记。本文将从基础参数、荧光理化性质、反应适配条件、实…

2026/8/11 15:51:57 阅读更多 →
收藏!小白程序员轻松入门大模型:哔哩哔哩AI-Native前端面试全解析

收藏!小白程序员轻松入门大模型:哔哩哔哩AI-Native前端面试全解析

本文详细分享了哔哩哔哩AI-Native开发工程师(前端)的面试经验,内容涵盖面试流程、考察重点及应对策略。适合希望在大模型领域发展的小白和程序员,助你轻松掌握前端技能,提升面试成功率。 哔哩哔哩 AI-Native开发工程师…

2026/8/11 15:51:57 阅读更多 →
Spread.NET 19.1.0 WinForms-NuGet .NET 10

Spread.NET 19.1.0 WinForms-NuGet .NET 10

Spread.NET v19.1包含超过 500 个 Excel 函数的完整 WinForms 电子表格 快速打造媲美 Excel 的电子表格体验,且完全不依赖 Excel。创建财务、预算/预测、科学、工程、医疗保健、保险、教育、制造等众多类似的 WinForms 商业应用程序。利用全面的 API创建企业级电子表…

2026/8/11 15:51:57 阅读更多 →
同城货运搬家系统:SpringBoot+Vue智能调度实战

同城货运搬家系统:SpringBoot+Vue智能调度实战

1. 项目背景与核心价值 同城货运搬家这个细分领域,在过去三年迎来了爆发式增长。根据行业数据显示,2022年同城货运市场规模已突破万亿,其中搬家服务占比超过35%。这个Java项目正是瞄准了这个高频刚需场景,通过技术手段解决传统搬家…

2026/8/11 15:50:57 阅读更多 →

日新闻

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/v…

2026/8/11 0:00:02 阅读更多 →
前后端分离项目中控制台与接口工具数据差异排查指南

前后端分离项目中控制台与接口工具数据差异排查指南

1. 问题现象解析:控制台与Apifox的数据差异 最近在调试一个前后端分离项目时,遇到了一个典型问题:后端服务在本地开发环境控制台能正常输出查询数据,但通过Apifox测试时却返回空结果。这种"控制台有数据,接口工具…

2026/8/11 0:00:03 阅读更多 →
AI编程实战:从Claude Code踩坑到游戏开发入门

AI编程实战:从Claude Code踩坑到游戏开发入门

1. 从“AI能帮我做游戏”到“AI让我重新学编程”最近身边不少朋友,尤其是一些非技术背景、但对游戏开发有浓厚兴趣的朋友,都在问我同一个问题:“听说现在用Claude Code这种AI编程工具,小白也能做游戏了,是真的吗&#…

2026/8/11 0:00:03 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/11 1:08:05 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/11 1:08:05 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/11 1:08:05 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/10 17:07:33 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/11 1:08:06 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/10 17:07:33 阅读更多 →