当前位置:首页 > 技术 > 正文内容

C# 依赖注入简介

访客 技术 2026年9月4日 1

什么是依赖注入?

依赖注入是一种设计模式,其中一个类(称为"服务")不负责创建它所依赖的对象,而是通过外部容器(如依赖注入容器)来获取这些对象。这样可以提高代码的可测试性和可维护性。

为什么需要依赖注入?

依赖注入有助于提高代码的灵活性和可测试性。例如,如果没有依赖注入,当需要更改某个依赖项时,可能需要修改很多地方。而使用依赖注入后,只需更改配置即可。


// 没有依赖注入的例子
public class OrderService
{
    private readonly Logger _logger = new Logger();
    
    public void CreateOrder()
    {
        _logger.Log("订单创建成功");
        // 其他业务逻辑...
    }
}

// 使用依赖注入的例子
public interface ILogger
{
    void Log(string message);
}

public class ConsoleLogger : ILogger
{
    public void Log(string message) => Console.WriteLine($"日志:{message}");
}

public class OrderService
{
    private readonly ILogger _logger;
    
    public OrderService(ILogger logger)
    {
        _logger = logger;
    }
    
    public void CreateOrder()
    {
        _logger.Log("订单创建成功");
    }
}

依赖注入的三种方式

  • 构造函数注入:通过类的构造函数接收依赖,是最常用的依赖注入方式。
  • 属性注入:通过公共属性接收依赖,适用于可选的依赖。
  • 方法注入:通过方法参数接收依赖,适用于仅在特定方法中需要的依赖。

Microsoft.Extensions.DependencyInjection

这是微软提供的一个依赖注入容器,支持多种服务生命周期(瞬时、作用域、单例)。


using Microsoft.Extensions.DependencyInjection;

public interface IUserService { }
public class UserService : IUserService { }

var services = new ServiceCollection();
services.AddTransient();
_serviceProvider = services.BuildServiceProvider();

在WPF中应用依赖注入

以下是一个简单的WPF示例,展示了如何使用依赖注入。


// 定义接口
public interface IDataService { }
public class DataService : IDataService { }

public interface ILoggerService { }
public class LoggerService : ILoggerService { }

public interface ISettingsService { }
public class SettingsService : ISettingsService { }

// 创建,注册,解析
public partial class App : Application
{
    private readonly IServiceProvider _serviceProvider;

    public App()
    {
        var serviceCollection = new ServiceCollection();
        ConfigureServices(serviceCollection);
        _serviceProvider = serviceCollection.BuildServiceProvider();
    }

    private void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<MainWindow>();
        services.AddScoped();
        services.AddTransient();
        services.AddSingleton();
    }

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
        mainWindow.Show();
    }
}

// 界面代码和后台代码省略
标签: C#

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。