【问题标题】:How to read configuration settings before initializing a Host in ASP .NET Core?如何在 ASP .NET Core 中初始化主机之前读取配置设置?
【发布时间】:2020-02-20 04:16:52
【问题描述】:

在初始化应用程序主机之前,我需要从应用程序的配置中读取一些设置来设置其他一些东西。

在 ASP .NET Core 2.x 中,在初始化应用程序主机之前读取设置我曾经执行以下操作:

public static void Main(string[] args)
{
    //...

    var configuration = new ConfigurationBuilder()
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .AddJsonFile("appsettings.json")
        .Build();

    //Do something useful with the configuration...

    var host = WebHost.CreateDefaultBuilder()
        .UseStartup<Startup>()
        .UseConfiguration(configuration)
        .Build();

    //...
}

在 ASP .NET Core 3.x 中 WebHost has been deprecated in favor of .NET Generic Host.
.NET 通用主机只有 .ConfigureHostConfiguration().ConfigureAppConfiguration() 不将构建配置作为参数,而是仅接受用于设置配置的委托。

对于 HTTP 工作负载,您仍然可以使用方法 .UseConfiguration()IWebHostBuilder 公开它,并且与以前基本相同:

public static void Main(string[] args)
{
    //...

    var configuration = new ConfigurationBuilder()
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .AddJsonFile("appsettings.json")
        .Build();

    //Do something useful with the configuration...

    var host = Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>()
                .UseConfiguration(configuration);
        })
        .Build();

    //...
}

但这仅适用于 HTTP 工作负载,不适用于 Worker Services.

为了在设置主机之前获取配置,我想出了以下方法:

public static void Main(string[] args)
{
    //...

    var configuration = ConfigureConfigurationBuilder(args)
        .Build();

    //Do something useful with the configuration...

    var host = Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(builder => ConfigureConfigurationBuilder(args, builder))
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .Build();

    //...
}

public static IConfigurationBuilder ConfigureConfigurationBuilder(string[] args, IConfigurationBuilder configurationBuilder = null)
{
    configurationBuilder ??= new ConfigurationBuilder();

    configurationBuilder
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .AddJsonFile("appsettings.json");

    return configurationBuilder;
}

基本上我已经编写了一个设置ConfigurationBuilder 并返回它的方法,这样我就可以重用相同的配置。这在实践中有效,但我构建了两次相同的配置。

有没有更简单/更正确的方法(适用于 HTTP 工作负载和非 HTTP 工作负载)在设置主机之前构建和重用配置?

【问题讨论】:

  • 恐怕不会,因为您在初始化主机之前无法获得配置。
  • @XingZou 事实上,我可以在设置主机之前设置配置,唯一的问题是我不能再次重复使用该配置,迫使我付出代价来初始化配置两次

标签: c# asp.net-core asp.net-core-3.0


【解决方案1】:

默认情况下ConfigureAppConfiguration() 将根据文档Default builder settings 加载appsettings.json

或者,如果您无法访问您的配置或收到System.NullReferenceException: 'Object reference not set to an instance ofan object.' 错误,这意味着IHostBuilder 无法在其基本路径中看到 json 文件。

检查或更改appsettings.json 文件属性,如下图所示:

  1. 将“构建操作”设置为“内容”
  2. 将“复制到输出目录”设置为“如果较新则复制”

【讨论】:

  • 我不确定这与我的问题有什么关系,问题不是“我无法访问配置”而是“我有一个 IConfiguration 实例已经准备好如何共享它HostBuiler" ?
【解决方案2】:

正确的问题,您真的需要为您的配置进行配置吗? 您可以使用另一个文件,并将其直接与实体绑定

configuration.GetSection("entity").Bind(entity);

如果我不明白你的意思,我只知道你需要它来进行依赖注入的设置,或者你不能使用它,所以你可以使用扩展来代替你的服务集合用你的配置做你想做的事,然后你在你的容器中得到设置

【讨论】:

  • 一些值在应用程序宿主和其他部分之间共享。一个具体的例子是在主机之前配置的记录器,以便我可以记录启动错误。记录器将记录到应用程序数据库,因此我想要一个连接字符串,记录器应用程序将在一个配置文件中使用该连接字符串。
【解决方案3】:

您可以清除CreateDefaultBuilder 添加的默认源,然后使用AddConfiguration extension method 添加预构建的IConfiguration

public static void Main(string[] args)
{
    //...

    var configuration = new ConfigurationBuilder()
        .AddEnvironmentVariables()
        .AddCommandLine(args)
        .AddJsonFile("appsettings.json")
        .Build();

    //Do something useful with the configuration...

    var host = Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(builder =>
        {
            builder.Sources.Clear();
            builder.AddConfiguration(configuration);
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .Build();

    //...
}

【讨论】:

  • 最佳答案,虽然我有一个附加问题,因为我还在 ConfigureAppConfiguration 中使用了 hostContext,这在上面的示例中不可用。我使用 hostContext 来获取 HostingEnvironment。
  • 如何从Startup访问配置?再次拨打ConfigureConfigurationBuilder
  • 您的 Startup 类可以通过 DI 在构造函数中接收 IConfiguration
  • 完美。我内联了configuration 语句,没有任何问题。 +1
  • 这似乎是正确的,但它会导致忽略 ConfigureWebHostDefaults 部分中的一些设置。例如,这种方法完全忽略了 webBuilder.UseUrls() 。有谁知道为什么?
猜你喜欢
  • 2018-02-18
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
相关资源
最近更新 更多