You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

依赖注入(DI)是否鼓励或遵循单一职责原则(SRP)?

依赖注入如何促进单一职责原则(SRP)

你说得没错——依赖的合理使用是SRP的核心,但DI的价值在于它会强制/引导你划清职责边界,而手动实例化依赖很容易让类悄悄承担额外职责却不自知。下面用具体例子对比说明:

反例:手动实例化依赖,违反SRP

假设我们有一个处理订单的类:

public class OrderService
{
    private readonly SqlConnection _dbConnection;
    private readonly FileLogger _logger;

    public OrderService()
    {
        // 手动初始化数据库连接,要处理连接字符串、超时配置
        _dbConnection = new SqlConnection("Server=...;Database=...");
        _dbConnection.Open();
        
        // 手动初始化日志类,要处理日志路径、级别
        _logger = new FileLogger(@"C:\logs\orders.log", LogLevel.Info);
    }

    public void CreateOrder(Order order)
    {
        // 核心业务:保存订单到数据库
        var command = _dbConnection.CreateCommand();
        command.CommandText = "INSERT INTO Orders (...) VALUES (...)";
        // ...执行逻辑
        
        // 记录日志
        _logger.Log($"Created order {order.Id}");
    }
}

这个OrderService现在承担了三个职责:

  1. 处理订单业务逻辑(本该是它唯一的职责)
  2. 初始化并管理数据库连接的生命周期
  3. 初始化并配置日志组件

手动创建依赖时,很自然就把“依赖创建”的职责塞进了业务类里,不知不觉就违反了SRP——这个类不再只专注于订单业务,还要操心数据库和日志的初始化细节。

正例:构造函数注入DI,遵循SRP

用DI重构后,我们先定义依赖的抽象:

public interface IDbConnectionFactory
{
    IDbConnection CreateConnection();
}

public interface ILogger
{
    void Log(string message);
}

然后OrderService只依赖抽象,通过构造函数注入:

public class OrderService
{
    private readonly IDbConnectionFactory _dbConnectionFactory;
    private readonly ILogger _logger;

    // 依赖通过构造函数注入,类不再负责创建依赖
    public OrderService(IDbConnectionFactory dbConnectionFactory, ILogger logger)
    {
        _dbConnectionFactory = dbConnectionFactory;
        _logger = logger;
    }

    public void CreateOrder(Order order)
    {
        // 核心业务:只处理订单逻辑,依赖的创建交给外部
        using var connection = _dbConnectionFactory.CreateConnection();
        var command = connection.CreateCommand();
        command.CommandText = "INSERT INTO Orders (...) VALUES (...)";
        // ...执行逻辑
        
        _logger.Log($"Created order {order.Id}");
    }
}

现在OrderService的职责只有一个:处理订单业务逻辑。数据库连接的创建、日志组件的初始化,这些职责都被剥离到专门的IDbConnectionFactory实现类和ILogger实现类里,每个类都只做自己的事。

DI促进SRP的关键原因

  • 强制职责分离:DI容器要求你把依赖的创建逻辑从业务类中抽离,你没办法在业务类里偷偷初始化依赖(除非刻意违规),这从结构上就避免了职责膨胀。
  • 依赖抽象而非具体:DI鼓励面向接口编程,业务类只关心依赖提供的能力,不关心具体实现,这让类更专注于自身业务,不会被依赖的实现细节干扰。
  • 降低修改扩散:如果数据库连接需要改配置,或者日志要换成Elasticsearch实现,只需要修改对应的工厂/日志类,OrderService完全不用动——这正是SRP要达到的目标:修改一个职责,不会影响其他职责。

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:12:45