.NET CORE 读取配置的三种方式
在.NET Core中,配置是通过各种配置提供程序来加载的,比如JSON文件、环境变量、命令行参数等等,appsettings.json是默认的配置文件。
需要考虑在控制器或者服务中如何注入IConfiguration接口?通常在Startup或者Program.cs中,会配置IConfiguration,通过依赖注入获取配置。
在构造函数中注入IConfiguration,然后使用像_config["Key"]这样的方式来读取值。不过这种方法可能不够结构化,特别是当配置比较复杂的时候。
使用选项模式,也就是IOptions<T>,这应该是推荐的做法。用户需要创建一个对应的配置类,比如AppSettings,然后在ConfigureServices中调用services.Configure<AppSettings>(Configuration.GetSection("SectionName"))。之后在需要的地方注入IOptions<AppSettings>,通过Value属性来访问配置。这种方法更类型安全,也方便管理。
直接通过键名来访问,比如Configuration.GetSection("Logging:LogLevel")["Default"],或者GetValue<string>("Key")。这些方法适用于简单的情况,但可能不适合复杂的配置结构。
需要注意不同环境下的配置文件,比如appsettings.Development.json,这些环境配置会自动覆盖基配置。所以需要了解环境变量的设置和配置的优先级。在较新版本的.NET(比如.NET 5或6),Program.cs可能使用了新的顶级语句,配置是在Host创建时构建的,所以需要确认如何正确获取Configuration实例。例如,使用var builder = WebApplication.CreateBuilder(args); 然后通过builder.Configuration来访问配置。
总结一下,应该涵盖以下几种方法:
直接通过键名使用冒号分层访问读取配置。
使用选项模式(IOptions<T>)来绑定配置到类。
绑定分层配置
注意环境配置和配置优先级的问题, 处理复杂结构如数组或嵌套对象的配置。
1. 直接通过键名读取配置
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value"
}public class HomeController : Controller
{
private readonly IConfiguration _config;
public HomeController(IConfiguration config)
{
_config = config;
}
public IActionResult Index()
{
var title = _config["Position:Title"]; // 使用冒号分层访问
var name = _config["Position:Name"]; // 使用冒号分层访问
var myKeyValue = _config["MyKey"]; // 使用冒号分层访问
return View();
}
}2. 使用选项模式(推荐)
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
},
"MyKey": "My appsettings.json Value"
}public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty;
}using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<PositionOptions>(builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();public class Test2Model : PageModel
{
private readonly PositionOptions _options;
public Test2Model(IOptions<PositionOptions> options)
{
_options = options.Value;
}
public ContentResult OnGet()
{
return Content($"Title: {_options.Title} \n" + $"Name: {_options.Name}");
}
}在上面的代码中,不会读取在应用启动后对 JSON 配置文件所做的更改。 若要读取在应用启动后的更改,请使用 IOptionsSnapshot
public class TestSnapModel : PageModel
{
private readonly PositionOptions _options;
public TestSnapModel(IOptionsSnapshot<MyOptions> snapshotOptionsAccessor)
{
_options = options.Value;
}
public ContentResult OnGet()
{
return Content($"Title: {_options.Title} \n" + $"Name: {_options.Name}");
}
}3. 绑定分层配置
public class Test22Model : PageModel
{
private readonly IConfiguration Configuration;
public Test22Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var positionOptions = new PositionOptions();
Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);
return Content($"Title: {_options.Title} \n" + $"Name: {_options.Name}");
}
}public class Test21Model : PageModel
{
private readonly IConfiguration Configuration;
public PositionOptions? positionOptions { get; private set; }
public Test21Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
positionOptions = Configuration.GetSection(PositionOptions.Position).Get<PositionOptions>();
return Content($"Title: {_options.Title} \n" + $"Name: {_options.Name}");
}
}4. 注意事项
键名匹配:配置类属性名需与JSON键名一致(默认不区分大小写)。
环境变量覆盖:可用export Key1__SubKey=Value(双下划线替代冒号)覆盖配置。
敏感数据:避免将密码等敏感信息直接写入appsettings.json,使用机密管理器或环境变量。
配置提供程序的典型顺序为:
appsettings.json
appsettings.{Environment}.json
用户机密
使用环境变量配置提供程序通过环境变量提供。
使用命令行配置提供程序通过命令行参数提供。