惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Vulnerabilities – Threatpost
L
LINUX DO - 热门话题
H
Hacker News: Front Page
Hacker News - Newest:
Hacker News - Newest: "LLM"
L
Lohrmann on Cybersecurity
Cisco Talos Blog
Cisco Talos Blog
O
OpenAI News
S
Securelist
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
H
Heimdal Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
Microsoft Azure Blog
Microsoft Azure Blog
MyScale Blog
MyScale Blog
Webroot Blog
Webroot Blog
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
Latest news
Latest news
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic
D
Docker
D
DataBreaches.Net
A
About on SuperTechFans
T
Tor Project blog
V
V2EX
G
Google Developers Blog
博客园 - Franky
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
I
InfoQ
H
Help Net Security
V2EX - 技术
V2EX - 技术
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Security Affairs
SecWiki News
SecWiki News
The Register - Security
The Register - Security
人人都是产品经理
人人都是产品经理
NISL@THU
NISL@THU
小众软件
小众软件
B
Blog
T
Threatpost
P
Palo Alto Networks Blog
博客园 - 【当耐特】
L
LangChain Blog
AWS News Blog
AWS News Blog
月光博客
月光博客
宝玉的分享
宝玉的分享

博客园 - hu晓峰

记winform程序异常排查 记一次wpf 背景图的坑点 【Unity踩坑】Unity项目管理员权限问题(Unity is running as administrator ) 微服务聚合查询 libmodbus编译为64位动态库 一文读懂Modbus协议:工业设备的“普通话“通信指南 Mysql union与union all有什么区别? 理解Systemd服务重启策略:on-failure vs always Redis分布式锁正确的实现方法 C# 解决串口通讯中,返回数据不完整 字典Dictionary.Add不是把新的元素插入到字典最后面 c# Avalonia 架构开发跨平台应用 ‌索引基数 MySQL InnoDB损坏修复:使用innodb_force_recovery 整数取低字节 C#汉字-区位码相互转化类 avalonia在linux下运行出现Default font family name can't be null or empty问题的解决 ICMP timestamp请求响应漏洞CVE-1999-0524解决方法 详解mysql的for update 使用Redis的SETNX命令实现分布式锁 ASP.NET Core中如何对不同类型的用户进行区别限流
依赖注入
hu晓峰 · 2026-03-06 · via 博客园 - hu晓峰

依赖注入​ 是一种设计模式,它把创建和管理对象依赖关系的控制权,从对象内部反转到外部容器。核心思想是“别找我,我会给你”

用一个生活中的比喻来理解:


比喻:开咖啡店

你想开一家咖啡店(CoffeeShop类),需要一台咖啡机(CoffeeMaker)。

传统方式(硬编码/内部创建):

  • 你自己去买零件、看说明书、组装一台咖啡机。咖啡店和这台特定咖啡机强绑定了。

  • 代码体现:在 CoffeeShop的构造函数里 new EspressoMachine()

依赖注入方式:

  • 你告诉一个“大管家”(DI容器):“我需要一台咖啡机,这是我的要求(接口)”。大管家会去它的仓库里,找来一台符合要求的咖啡机(可能是 EspressoMachine,也可能是 DripCoffeeMaker装好,送到你店里。

  • 不关心咖啡机从哪来、怎么造的,只管用就行了。

  • 代码体现:CoffeeShop的构造函数声明需要一个 ICoffeeMaker接口的参数,外部(容器)负责传入一个具体的实现(如 EspressoMachine)。


核心概念

  1. 依赖:一个对象正常工作所需要的其他对象(如 CoffeeShop依赖 CoffeeMaker)。

  2. 注入由外部(通常是DI容器)在创建对象时,将依赖传递给它。主要注入方式:

    • 构造函数注入(最推荐):通过构造函数参数传入。保证了对象在创建后就是完整的、可用的。

    • 属性/Setter注入:通过公开的属性设置。对象可能在某个阶段依赖不完整。

    • 方法注入:通过特定方法的参数传入。


为什么用依赖注入?(优点)

  1. 解耦CoffeeShop不依赖具体的 EspressoMachine,只依赖 ICoffeeMaker接口。想换咖啡机品牌?只需配置容器,不用改 CoffeeShop的代码。符合“依赖倒置”原则

  2. 可测试性:在单元测试时,可以轻松传入一个“模拟咖啡机”(Mock对象)来测试 CoffeeShop的行为,而不需要真的启动一台咖啡机。

  3. 可维护性:所有对象的创建和依赖关系在一个地方(容器)集中管理,就像一份“装配说明书”,清晰明了。

  4. 生命周期管理:容器可以帮你管理对象的生命周期(如单例、每次请求新建一个)。


一个简单的代码示例

没有DI(强耦合,难测试):

public class CoffeeShop {
    private EspressoMachine _machine; 

使用DI(解耦,易测试):

// 1. 定义接口
public interface ICoffeeMaker {
    void Brew();
}

实际应用

在现代框架(如 Spring, .NET Core, Angular 等)中,都有一个IoC容器(控制反转容器)来自动帮你完成依赖注入。

  • 注册:你告诉容器:“遇到 ICoffeeMaker请求时,给一个 EspressoMachine实例”。

  • 解析:当你需要一个 CoffeeShop时,容器会自动创建 EspressoMachine,再创建 CoffeeShop并把咖啡机“注入”给它。

一句话总结:依赖注入是一种“将对象的组装和使用分离”的模式。它的核心价值在于解耦提升可测试性,是现代软件架构的基石之一。