C#中的依赖注入:实用指南与示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:什么是依赖注入以及为什么需要它

依赖注入(DI)是实现SOLID中依赖倒置原则的关键设计模式之一。在实践中,这意味着对象不会自行创建其依赖项,而是从外部获取它们。这使得代码灵活、可测试且松散耦合。

在C#和.NET生态系统中,DI已成为事实上的标准。从.NET Core开始,平台内置了自身的依赖注入容器,用于ASP.NET Core、后台服务甚至控制台应用程序。不理解DI就无法想象现代C#开发。

在本文中,我们将通过实际示例分析DI:从手动注入到使用内置的.NET容器。您将看到如何消除紧耦合,并使代码适合单元测试。



没有依赖注入的问题

设想一个典型场景:OrderService类处理订单并发送电子邮件通知。没有DI的代码如下所示:

public class EmailSender{    public void Send(string to, string subject, string body)    {        Console.WriteLine($"发送电子邮件至 {to}: {subject}");    }}

public class OrderService{ private EmailSender _emailSender;

public OrderService() { // 紧耦合——类自行创建依赖项 _emailSender = new EmailSender(); }

public void ProcessOrder(int orderId) { // 订单处理逻辑... _emailSender.Send("user@example.com", "订单已确认", $"您的订单 #{orderId} 已接收。"); }}

问题在哪里?OrderService紧耦合于EmailSender的具体实现。如果我们想将电子邮件发送替换为短信或日志记录,就必须修改OrderService的代码。测试也变得复杂:无法将真实的EmailSender替换为模拟对象。



解决方案:通过构造函数注入依赖项

迈向DI的第一步是提取抽象(接口)并通过构造函数传递依赖项。这称为构造函数注入。



步骤1:创建接口

public interface INotificationService{    void Send(string to, string subject, string body);}


步骤2:实现接口

public class EmailSender : INotificationService{    public void Send(string to, string subject, string body)    {        Console.WriteLine($"电子邮件已发送:{subject} -> {to}");    }}

public class SmsSender : INotificationService{ public void Send(string to, string subject, string body) { Console.WriteLine($"短信已发送:{subject} -> {to}"); }}


步骤3:通过构造函数注入依赖项

public class OrderService{    private readonly INotificationService _notificationService;

// 依赖项从外部传入 public OrderService(INotificationService notificationService) { _notificationService = notificationService; }

public void ProcessOrder(int orderId) { // 订单处理逻辑... _notificationService.Send("user@example.com", "订单已确认", $"您的订单 #{orderId} 已接收。"); }}

现在OrderService不知道具体使用的是哪种实现。我们可以传入EmailSender、SmsSender或任何其他实现INotificationService的类。代码变得灵活且可测试。



在.NET中使用内置的IoC容器

手动创建所有依赖项并不方便。.NET有一个内置容器(IoC容器),可以自动管理对象的生命周期。让我们看一个控制台应用程序的示例。



步骤1:安装包

博客

书籍推荐