什么是依赖注入?

什么是依赖注入?

技术背景

在软件开发中,一个对象常常需要依赖其他对象来完成其功能。传统方式下,对象自己负责创建和管理其依赖的对象,这会导致类之间的高度耦合,使代码难以测试和维护。依赖注入(Dependency Injection,简称 DI)应运而生,它是一种实现松耦合的设计模式,将对象的创建和管理责任从使用对象的类中分离出来。

实现步骤

1. 定义依赖接口

首先,需要定义依赖对象的接口,这样可以让使用依赖的类依赖于抽象而不是具体实现。例如:

1
2
3
4
public interface IEngine
{
void Start();
}

2. 实现依赖接口

实现上述定义的接口,提供具体的功能。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class GasEngine : IEngine
{
public void Start()
{
Console.WriteLine("I use gas as my fuel!");
}
}

public class ElectricityEngine : IEngine
{
public void Start()
{
Console.WriteLine("I am electrocar");
}
}

3. 创建使用依赖的类

在使用依赖的类中,通过构造函数或 setter 方法接收依赖对象。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Car
{
private readonly IEngine _engine;
public Car(IEngine engine)
{
_engine = engine;
}

public void Run()
{
_engine.Start();
}
}

4. 注入依赖

在客户端代码中,创建依赖对象并注入到使用依赖的类中。例如:

1
2
3
4
Car gasCar = new Car(new GasEngine());
gasCar.Run();
Car electroCar = new Car(new ElectricityEngine());
electroCar.Run();

核心代码

构造函数注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Client
{
Service service;

Client(Service service)
{
this.service = service;
}

public void doSomeThingInClient()
{
service.doSomeThingInService();
}
}

Setter 注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Client
{
Service service;

public void setService(Service service)
{
this.service = service;
}

public void doSomeThingInClient()
{
service.doSomeThingInService();
}
}

最佳实践

使用接口编程

让类依赖于接口而不是具体实现,这样可以提高代码的灵活性和可替换性。例如,上述的 Car 类依赖于 IEngine 接口,而不是具体的 GasEngineElectricityEngine 类。

借助 IoC 容器

当项目中的依赖关系变得复杂时,可以使用 IoC(Inversion of Control)容器来管理依赖对象的创建和注入。常见的 IoC 容器有 Spring、Guice 等。在配置阶段,IoC 容器可以定义抽象与具体实现之间的映射关系,以及依赖对象的生命周期管理策略。

常见问题

1. 配置文件硬编码问题

在使用依赖注入时,配置文件中可能会硬编码具体的实现类,这可能会降低代码的灵活性。可以通过在运行时动态指定实现类,或者使用配置文件来管理实现类的映射关系。

2. 运行时更改对象问题

如果需要在运行时更改注入的对象,可以使用工厂模式或策略模式,根据不同的条件创建不同的对象。

3. 代码维护问题

当需要更改一个类的依赖时,可能需要同时修改类本身和配置文件。为了减少这种影响,可以使用统一的配置管理工具,或者采用自动化的配置生成工具。

4. 未注入属性的模拟问题

如果一个类的某个属性没有被注入,可能会增加模拟测试的难度。可以通过使用 setter 方法或构造函数来确保所有依赖都能被注入,从而方便进行模拟测试。


什么是依赖注入?
https://119291.xyz/posts/2025-05-09.what-is-dependency-injection/
作者
ww
发布于
2025年5月9日
许可协议