.NET CORE 读取配置的三种方式

152

在.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

  • 用户机密

  • 使用环境变量配置提供程序通过环境变量提供。

  • 使用命令行配置提供程序通过命令行参数提供。

5. 官方文档

https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view=aspnetcore-9.0https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/options?view=aspnetcore-9.0https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/environments?view=aspnetcore-9.0