开发者

C#中的依赖注入Dependency Injection DI的实现步骤

目录
  • 1. 基本概念
  • 2. 配置依赖注入的步骤
    • 步骤1:定义服务接口和实现类
    • 步骤2:注册服务到容器
    • 步骤3:注入服务到目标类
  • 3. 在非Web应用(如wpF/控制台)中使用DI
    • 4. 高级用法
      • 4.1 注入多个实现(命名或策略模式)
      • 4.2 使用工厂模式动态创建服务
    • 4.3 生命周期管理注意事项
      • 5. 常见问题解决
        • 6. 总结表格

          在C#中,依赖注入(Dependency Injection, DI)是一种实现控制反转(IoC)的设计模式,用于解耦组件依赖关系。以下是基于 .NET Core/ .NET 5+ 的依赖注入配置详细步骤和用法:

          1. 基本概念

          • 服务(Service):被注入的依赖项(如接口、类)。
          • 容器(Container):管理服务的创建和生命周期(如 IServiceCollection)。
          • 生命周期
            • Transient:每次请求创建新实例。
            • Scoped:同一作用域内共享实例(如一次HTTP请求)。
            • Singleton:全局单例。

          2. 配置依赖注入的步骤

          步骤1:定义服务接口和实现类

          // 定义接口
          public interface IMyService
          {
              string GetMessage();
          }
          
          // 实现接口
          public class MyService : IMyService
          {
              public string GetMessage() => "Hello from MyService!";
          }

          步骤2:注册服务到容器

          在 Program.cs 或 Startup.cs(.NET 6+ 通常使用 Program.cs):

          var builder = WebApplication.CreateBuilder(args);
          
          // 注册服务(生命周期可选)
          builder.Services.AddTransient<IMyService, MyService>();      // 瞬时
          builder.Services.AddScoped<IMyService, MyService>();         // 作用域
          builder.Services.AddSingleton<IMyService, MyService>();      // 单例
          
          // 直接注册类(无接口)
          builder.Services.AddTransient<MyService>();

          步骤3:注入服务到目标类

          通过构造函数注入:

          public class MyController : ControllerBase
          {
              private readonly IMyService _service;
          
              // 构造函数自动注入
              public MyController(IMyService service)
              {
                  _service = service;
              }
          
              [HttpGet]
              public IActionResult Get()
              {
                  return Ok(_service.GetMessage());
              }
          }

          3. 在非Web应用(如WPF/控制台)中使用DI

          WPF 示例

          安装NuGet包

          Install-Package Microsoft.Extensions.DependencyInjection

          配置DI容器(在 App.xaml.cs):

          public partial class App : Application
          {
              public IServiceProvider ServiceProvider { get; private set; }
          
              protected override void OnStartup(StartupEventArgs e)
              {
                www.devze.com  var services = new ServiceCollection();
                  
                  // 注册服务
                  services.AddTransient<IMyService, MyService>();
                  services.AddSingleton<MainWindow>(); // 注册主窗口SweRmFykP
          
                  ServiceProvider = services.BuildServiceProvider();
                  
                  // 解析主窗口并显示
                  var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
                  mainWindow.Show();
              }
          }

          在窗口/ViewModel中注入

          public partial class MainWindow : Window
          {
              public MainWindow(IMyService service)
              {
                  InitializeComponent();
                  var message = service.GetMessage(); // 使用注入的服务
              }
          }

          4. 高级用法

          4.1 注入多个实现(命名或策略模式)

          // 注册多个实现
          builder.Services.AddTransient<IjavascriptMyService, ServiceA>();
          builder.Services.AddTransient<IMyService, ServiceB>();
          
          // 通过 IEnumerable<T> 获取所有实现
          public class Consumer
          {
              publiwww.devze.comc Consumer(IEnumerable<IMyService> services)
              {
                  foreach (var service in services)
                  {
                      service.DOSomething();
                  }
              }
          }

          4.2 使用工厂模式动态创建服务

          builder.Services.AddTransient<IMyService>(provider => 
          {
              var config = provider.GetRequiredService<IConfiguration>();
              return new MyService(config.GetValue<string>("Mode"));
          });

          4.3 生命周期管理注意事项

          • 避免Singleton依赖Scoped服务:可能导致Captive Dependency问题。
          • IDisposable处理:容器会自动释放实现了 IDisposable 的服务。

          5. 常见问题解决

          错误:未注册服务

          System.InvalidOperationException: No service for type 'IMyService' has been registered.

          解决:检查服务是否在 IServiceCollection 中正确注册。

          循环依赖

          重构代码以避免构造函数循环引用,或用 Lazy<Tandroid> 延迟初始化。

          6. 总结表格

          操作代码示例说明
          注册Transient服务services.AddTransient<IMyService, MyService>();每次请求新实例
          注册Scoped服务services.AddScoped<IMyService, MyService>();同一作用域内共享实例
          注册Singleton服务services.AddSingleton<IMyService, MyService>();全局单例
          构造函数注入public MyClass(IMyService service)自动解析依赖
          手动解析服务var service = provider.GetRequiredService<IMyService>();从容器获取实例

          通过以上步骤,可以灵活地在C#项目中配置和使用依赖注入,提升代码的可测试性和可维护性。

          到此这篇关于C#中的依赖注入Dependency Injection DI的实现步骤的文章就介绍到这了,更多相关C# 依赖注入内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

          0

          上一篇:

          下一篇:

          精彩评论

          暂无评论...
          验证码 换一张
          取 消

          最新开发

          开发排行榜