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

.NET 6中用IOptionsMonitor注入配置到IServiceCollection,避免BuildServiceProvider

.NET 6 中使用 IOptionsMonitor 替代 BuildServiceProvider 实现配置注入

现有配置与代码

appsettings.json 配置

{
  "$schema": "./appsettings-schema.json",  
  "ConnectionStrings": {
    "dbDSN": "Server=.;Database=demodb;User Id=demo;Password=123"    
  },
  "ConnectPoint": {
    "siteAPI": "https://workersite.com/api"
  }
}

记录类定义

public record SiteConfiguration {
    public ConnectPoint ConnectPoint { get; set; }
}
public record ConnectPoint {
    public string siteAPI { get; set; } = string.Empty;
}

原有静态注入类

public static class ServiceInjection {
    public static IServiceCollection AddConnectServices(this IServiceCollection services, IOptions<SiteConfiguration> configuration) {
        
        services.AddSingleton<IAPIClient>(
            new APIClient(              
                    new HttpClient {
                        BaseAddress = new Uri(configuration.Value.ConnectPoint.siteAPI)
                    }));
        return services;
    }
}

原有存在问题的实现

原代码通过BuildServiceProvider提前解析配置,不符合.NET 6依赖注入的最佳实践:

services.Configure<SiteConfiguration>();
var serviceProvider = services.BuildServiceProvider();
var opt = serviceProvider.GetRequiredService<IOptions<SiteConfiguration>>().Value;
services.AddConnectServices(opt); // 原代码存在笔误,此处应为传入IOptions实例而非Value

修改后的解决方案

1. 调整静态注入类,依赖注入获取 IOptionsMonitor

修改注入方法,通过服务提供者工厂延迟解析IOptionsMonitor,既避免提前构建服务容器,又支持配置变更监听:

public static class ServiceInjection {
    public static IServiceCollection AddConnectServices(this IServiceCollection services) {
        // 利用服务提供者工厂,在创建IAPIClient时自动注入依赖
        services.AddSingleton<IAPIClient>(serviceProvider => {
            var configMonitor = serviceProvider.GetRequiredService<IOptionsMonitor<SiteConfiguration>>();
            var currentConfig = configMonitor.CurrentValue;
            
            return new APIClient(
                new HttpClient {
                    BaseAddress = new Uri(currentConfig.ConnectPoint.siteAPI)
                });
        });
        return services;
    }
}

2. .NET 6 顶级语句中配置服务

在Program.cs中直接完成配置绑定与服务注入,无需Startup.cs:

var builder = WebApplication.CreateBuilder(args);

// 将配置绑定到SiteConfiguration
builder.Services.Configure<SiteConfiguration>(builder.Configuration);

// 调用修改后的注入方法,无需手动传递配置
builder.Services.AddConnectServices();

var app = builder.Build();

// 后续中间件配置逻辑...
app.Run();

关键说明

  • IOptionsMonitor<SiteConfiguration>支持实时监听配置变更,若后续siteAPI通过配置中心或文件更新,可通过configMonitor.OnChange方法处理动态更新逻辑(如需动态修改HttpClient的BaseAddress,需额外设计实例更新机制)。
  • 移除BuildServiceProvider调用,避免额外创建服务容器实例带来的性能损耗与潜在的依赖不一致问题。
  • 采用工厂方法延迟解析依赖,符合.NET依赖注入的设计原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 02:45:37