如何在注入前修改IOptions?.NET 7预览版配置场景
问题描述
我正在使用.NET 7预览版,将密钥存储为环境变量,尝试将其分配给通过IOptions注入的类。
其他非密钥参数存储在appsettings.json中:
"MyServerName": { "EnvironmentName": "MyServerName", "EndpointAddress": "net.tcp://MyServerName:8201/Services/" }
我的配置绑定类如下:
public class MyEnvironment { public string EnvironmentName { get; set; } public string EndpointAddress { get; set; } public string AzureAuthRelayConStr { get; set; } public string AzureStorageConnectionStr { get; set; } }
在Program.cs中:
var MyEnvironment = new MyEnvironment(); builder.Configuration.GetSection(machineName).Bind(MyEnvironment); // 问题所在:此处修改无法持久化。我知道可在构造函数中添加,但绑定前修改的正确方法是什么? MyEnvironment.AzureStorageConnectionStr = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING"); builder.Services.Configure<MyEnvironment>(builder.Configuration.GetSection(machineName));
上述代码中倒数第二行的修改无法持久化,我想了解绑定前修改配置的正确方法是什么?另外,能否不通过自定义类和JSON,直接向IOptions传递List或通用参数?
解决方案
一、修改配置并持久化的正确方法
你当前的问题核心是:手动修改独立实例后,又通过Configure<MyEnvironment>从配置节重新绑定,覆盖了之前的修改。推荐两种靠谱的解决方式:
方式1:直接修改配置系统中的值
在绑定选项前,把环境变量的值写入对应的配置节,让配置系统自带该参数:
var myEnvSection = builder.Configuration.GetSection(machineName); // 将环境变量值写入配置节 myEnvSection["AzureStorageConnectionStr"] = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING"); // 再基于更新后的配置节绑定选项 builder.Services.Configure<MyEnvironment>(myEnvSection);
方式2:通过Configure委托合并值
利用Configure的重载,先绑定配置文件内容,再手动覆盖环境变量值,一步完成:
builder.Services.Configure<MyEnvironment>(options => { // 先绑定appsettings中的配置项 builder.Configuration.GetSection(machineName).Bind(options); // 用环境变量覆盖指定参数 options.AzureStorageConnectionStr = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING"); });
二、直接向IOptions传递List或通用参数
完全可以,不需要自定义类,两种实现场景:
场景1:从配置系统绑定集合
如果配置文件(或环境变量)本身有集合结构,比如appsettings.json中:
"MyStringList": [ "ItemA", "ItemB", "ItemC" ]
可直接绑定到List<string>:
builder.Services.Configure<List<string>>(builder.Configuration.GetSection("MyStringList")); // 使用时注入IOptions<List<string>>即可
场景2:手动构造集合并配置
如果不需要从配置文件读取,直接构造集合注入:
// 带名称的配置,方便区分多个同类型集合 builder.Services.Configure<List<int>>("MyCustomIntList", options => { options.Add(100); options.Add(200); }); // 使用时注入IOptionsSnapshot<List<int>>,通过名称获取 // var intList = optionsSnapshot.Get<List<int>>("MyCustomIntList");
内容的提问来源于stack exchange,提问作者William YK
相关产品推荐
相关产品推荐

