登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
每日签到
每天签到奖励2圆-6圆
发帖说明
VIP申请
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
VIP申请
VIP网盘
网盘
联系我们
每日签到
道具
勋章
任务
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
依赖注入(DI)与控制反转(IoC)
依赖注入(DI)与控制反转(IoC)
[ 复制链接 ]
寅斫
2025-6-3 14:51:16
导航
1前言
2什么是依赖注入与控制反转
2.1控制反转
2.2依赖注入
3为什么要使用依赖注入与控制反转
3.1解耦
3.2单元测试
4IoC容器
5结束语
1 前言
依赖注入(DI)与控制反转(IoC)可能是一些开发小伙伴耳熟但又不能详的两个词,经常看到它们的名字,但又不理解。这两个词来源于英文直译,看似高深莫测,其实非常简单,并且在一些开发场景中扮演着不可或缺的角色,比如单元测试离不开依赖注入,IoC容器是插件框架的最佳拍档等,本文尝试以最简单的方式阐述这两种思想在开发中的应用。文章来源:https://www.wubayue.com
2 什么是依赖注入与控制反转
2.1 控制反转
在解释控制反转前,首先需要理解什么是“正转”:A依赖于B,并且A掌控B的创建销毁,此时A控制了B,即为“正转”。
当B的创建销毁在A之外完成,B脱离了A的控制,称之为控制反转(IoC:Invertion of Control)。
public class A
{
private B _b;
public A()
{
// 因为A掌控B的创建,因此A控制了B,此为“正转”
_b = new B();
}
}
复制代码
2.2 依赖注入
对象之间的依赖不再由内部创建,而是由外部传递,称之为依赖注入(DI:Dependency Injection)。
控制反转是设计思想,依赖注入是实现手段。两者缺一不可:
public class A
{
private B _b;
// B由外部注入,称之为依赖注入
public A(B b)
{
// B由外部创建,脱离了A的控制,称之为控制反转
_b = b;
}
}
复制代码
如上代码示例的是构造函数注入,另一种常见的依赖注入方式是属性注入:
public class A
{
public B B { get; set; }
}
void main()
{
A a = new A();
B b = new B();
// 属性注入
a.B = b;
}
复制代码
3 为什么要使用依赖注入与控制反转
3.1 解耦
在软件行业,有一条黄金法则叫“高内聚,低耦合”。耦合表示使用(或称为依赖),比如B使用了A,即B耦合了A,只要类的数量一多,类之间千丝万缕的耦合关系会成为巨大挑战,高内聚就是把相同的功能放在一起,这样类之间的耦合关系就会减少,通过提升内聚来减少类之间的耦合是一种常见的解耦方式。如上图,C依赖B,B依赖A,原本是两级依赖关系,通过将B中的部分功能向A内聚(前提是这部分功能原本就具有相关性),实现了B、C都依赖于A的一级依赖关系,B、C之间完成了解耦。
解耦除了完全消除依赖关系以外,另一种方式是将紧耦合转换为松耦合。先解释一下松紧耦合的概念,我们打开电脑机箱找到主机板上的南北桥芯片,可以看到它们是完全焊接在主板上的,这种不可替换的连接即为紧耦合;再找到内存条,发现它们可以拆卸并更换为其它品牌,这种可替换的连接即为松耦合。大部分时候,在软件设计开发时都应使用松散耦合,而依赖注入就是实现松散耦合非常好的一种方式。
如果我们再稍思考一下,主板上的内存条为什么能安装不同的品牌?原因是有相关技术标准,比如长宽尺寸,针脚数量,通信标准等,不同的内存条厂商,只要遵循标准生产出来的内存条就能安装到同一块主板上。在软件开发中,让主板支持不同厂商的内存条称之为可扩展性,定义内存条接口标准称之为抽象,根据标准生产内存条称之为面向抽象编程(或面向接口编程)。因此为了使软件模块具备更好的扩展性,除了使用依赖注入,还应注入抽象而非具体。
3.2 单元测试
不了解单元测试的小伙伴可先阅读我的另一篇文章《单元测试从入门到精通》。在单元测试中如果没有依赖注入,几乎寸步难行,通过简单的代码来示例:
难以测试的代码:
// 被测对象
public class House
{
private Bedroom _bedroom;
House()
{
// 内部构造协作对象,难以被测试。
_bedroom = new Bedroom();
}
// ...
}
// 测试用例
public void TestThisIsReallyHard()
{
House house = new House();
// 无法在测试过程中对Bedroom进行属性赋值、行为方法调用等,测试寸步难行
// ...
}
复制代码
易于测试的代码:
// 被测对象
public class House
{
private Bedroom _bedroom;
// 注入协作对象,可测试性好。
House(Bedroom b)
{
_bedroom = b;
}
// ...
}
// 测试用例
public void TestThisIsEasyAndFlexible()
{
// Bedroom对象在掌控之中,易于测试
Bedroom bedroom = new Bedroom();
House house = new House(bedroom);
// ...
}
复制代码
4 Ioc容器
在稍复杂的软件产品中,通常会遇到两个关于对象的问题:一是对象的数量众多,如何统一对它们进行管理,比如统一管理对象的创建销毁过程,每个对象的生命周期;二是对象之间可能存在多重复杂的依赖关系,如何对这些依赖关系进行管理,比如谁先创建谁后创建,被依赖的对象如何注入依赖对象等。
针对如上两个问题的解决方案就是IoC容器(IoC Container),IoC容器是一个对象管理器,它统一管理对象的创建销毁过程、生命周期、依赖关系,以及提供自动注入、根据配置创建对象等一系列便捷功能。如下代码使用 Autofac(C#开源IoC容器)进行了简单示例:
// 使用开源IoC容器Autofac
using Autofac;
namespace AutofacDemo
{
class A
{ }
class B
{
A _a;
// 只需要声明需要注入的对象,由容器自动完成依赖对象的创建与注入
public B(A a)
{
_a = a;
}
}
internal class Program
{
static void Main(string[] args)
{
// 将类型注册至容器中
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType();
// 设置对象的生命周期(单例模式)
builder.RegisterType<B>().SingleInstance();
// 构造IoC容器
IContainer container = builder.Build();
// 从容器中获取对象
B b = container.Resolve<B>();
}
}
}
复制代码
5 结束语
依赖注入与控制反转的思想诞生于软件开发追求高内聚、低耦合的历史进程中,20世纪90年代末已在软件设计模式、单元测试中使用。2002年Java的Spring框架搭载IoC容器、AOP等大杀器风靡全球,DI与IoC被更多的开发者关注。直到最近的项目中涉及插件化框架,而IoC容器又是插件架构的最佳拍档,因此将其整理成文。如能给人予帮助,不甚荣幸。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
依赖
注入
DI
控制
反转
相关帖子
实现一个python依赖注入demo,为了开发框架做准备
突破WAF!帆软模板注入漏洞利用新姿势
MAVEN构建分离依赖JAR
ESP32-WIFI-WebUI控制LED
COOKIE注入工具
【译】更好地控制您的 Copilot 代码建议
WPF依赖属性学习
【EF Core】实体类的依赖注入
vip免费申请,1年只需15美金$
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
安全
实现一个python依赖注入demo,为了开发框架做准备
0
792
翁真如
2025-06-26
业界
突破WAF!帆软模板注入漏洞利用新姿势
0
1066
绘纵
2025-07-22
业界
MAVEN构建分离依赖JAR
0
607
森萌黠
2025-08-08
业界
ESP32-WIFI-WebUI控制LED
0
216
吟氅
2025-08-10
程序
COOKIE注入工具
0
76
新程序
2025-08-19
安全
【译】更好地控制您的 Copilot 代码建议
0
323
呼延含玉
2025-09-02
业界
WPF依赖属性学习
0
115
诉称
2025-09-04
业界
【EF Core】实体类的依赖注入
0
1000
笃迩讦
2025-09-06
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
寅斫
2025-6-3 14:51:16
关注
0
粉丝关注
9
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
敖可
9984
杭环
9988
凶契帽
9988
4
氛疵
9988
5
黎瑞芝
9988
6
猷咎
9986
7
里豳朝
9986
8
肿圬后
9986
9
蝓俟佐
9984
10
虽裘侪
9984
查看更多