.NET Core 9中如何通过依赖注入从appsettings.json为常量或静态只读字段赋值
.NET Core 9中如何通过依赖注入从appsettings.json为常量或静态只读字段赋值
首先得把你思路里的两个核心问题说清楚:
const是编译期常量,只能用字面量或其他编译阶段就能确定的值赋值,根本没法用运行时从配置文件读取的内容初始化- 静态
readonly字段如果在类初始化阶段赋值,此时DI容器还没完成初始化,_config肯定是null,直接用会触发空引用异常
那正确的做法其实很贴合.NET的依赖注入设计,把MagicStrings从静态常量类改成可注入的服务类就行,具体步骤如下:
第一步:重构MagicStrings类
把原来的常量改成实例属性,在构造函数里注入IConfiguration,把配置读取+默认值 fallback 的逻辑封装在属性里:
internal class MagicStrings { private readonly IConfiguration _config; // 构造函数注入IConfiguration,确保参数非空 public MagicStrings(IConfiguration config) { _config = config ?? throw new ArgumentNullException(nameof(config)); } // 优先读取appsettings的值,没有就用默认值 public string HttpClientName => _config.GetValue<string>("HttpClientBasicConfig:HttpClientName") ?? "X_HttpClient"; // 其他需要的配置项都可以按这个格式添加 }
第二步:把服务注册到DI容器
在Program.cs里将这个类注册为单例服务(配置不会频繁变化,单例足够):
var builder = WebApplication.CreateBuilder(args); // 注册MagicStrings为单例服务 builder.Services.AddSingleton<MagicStrings>(); // 其他服务注册(比如你的Worker、IHttpClientFactory等) builder.Services.AddHostedService<Worker>(); builder.Services.AddHttpClient();
第三步:在Worker中注入使用
现在你可以直接在Worker的构造函数里注入MagicStrings,然后用它的属性就行,不用再重复写配置读取逻辑:
public class Worker : BackgroundService { private readonly IHttpClientFactory _httpClientFactory; private readonly MagicStrings _magicStrings; public Worker(IHttpClientFactory httpClientFactory, MagicStrings magicStrings) { _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); _magicStrings = magicStrings ?? throw new ArgumentNullException(nameof(magicStrings)); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var httpClient = _httpClientFactory.CreateClient(_magicStrings.HttpClientName); // 后续业务逻辑... } }
(可选)如果非要用静态访问方式(不推荐)
如果你实在想保留类似静态类的调用方式,也可以用静态属性结合初始化方法,但这种方式有明显缺点:不利于单元测试(静态状态难Mock)、初始化顺序出错会导致空引用。示例如下:
internal static class MagicStrings { private static IConfiguration _config; // 必须在DI容器初始化后调用这个方法赋值 public static void Initialize(IConfiguration config) { _config = config ?? throw new ArgumentNullException(nameof(config)); } public static string HttpClientName => _config.GetValue<string>("HttpClientBasicConfig:HttpClientName") ?? "X_HttpClient"; }
然后在Program.cs里初始化:
var builder = WebApplication.CreateBuilder(args); // 初始化静态类 MagicStrings.Initialize(builder.Configuration);
总结
推荐用第一种依赖注入的实例服务方式,它完全符合.NET的设计原则,代码可测试性更强,也不会有静态状态带来的潜在问题。
备注:内容来源于stack exchange,提问作者sTx
相关产品推荐
相关产品推荐

