C# 如何在ASP.NET Core中初始化主机之前读取配置设置?

C# 如何在ASP.NET Core中初始化主机之前读取配置设置?,c#,asp.net-core,asp.net-core-3.0,C#,Asp.net Core,Asp.net Core 3.0,在初始化应用程序主机之前,我需要从应用程序的配置中读取一些设置,以设置其他内容 在ASP.NET Core 2.x中,在初始化应用程序主机之前读取设置,我用于执行以下操作: publicstaticvoidmain(字符串[]args) { //... var configuration=new ConfigurationBuilder() .AddenEnvironmentVariables() .AddCommandLine(args) .AddJsonFile(“appsettings.j

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

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

publicstaticvoidmain(字符串[]args)
{
//...
var configuration=new ConfigurationBuilder()
.AddenEnvironmentVariables()
.AddCommandLine(args)
.AddJsonFile(“appsettings.json”)
.Build();
//对配置执行一些有用的操作。。。
var host=WebHost.CreateDefaultBuilder()
.UseStartup()
.UseConfiguration(配置)
.Build();
//...
}
在ASP.NET Core 3.x中
WebHost

.NET通用主机只有
.ConfigureHostConfiguration()
.ConfigureAppConfiguration()
,它们不将生成的配置作为参数,而是只接受用于设置配置的委托

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

publicstaticvoidmain(字符串[]args)
{
//...
var configuration=new ConfigurationBuilder()
.AddenEnvironmentVariables()
.AddCommandLine(args)
.AddJsonFile(“appsettings.json”)
.Build();
//对配置执行一些有用的操作。。。
var host=host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder=>
{
webBuilder.UseStartup()
.使用配置(配置);
})
.Build();
//...
}
但这只适用于HTTP工作负载,而不适用于

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

publicstaticvoidmain(字符串[]args)
{
//...
var配置=ConfigureConfigurationBuilder(args)
.Build();
//对配置执行一些有用的操作。。。
var host=host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(builder=>ConfigureConfigurationBuilder(args,builder))
.ConfigureWebHostDefaults(webBuilder=>
{
webBuilder.UseStartup();
})
.Build();
//...
}
公共静态IConfigurationBuilder ConfigureConfigurationBuilder(字符串[]args,IConfigurationBuilder configurationBuilder=null)
{
configurationBuilder???=新的configurationBuilder();
配置生成器
.AddenEnvironmentVariables()
.AddCommandLine(args)
.AddJsonFile(“appsettings.json”);
返回配置生成器;
}
基本上,我编写了一个方法,用于设置
ConfigurationBuilder
并返回它,以便可以重用相同的配置。这在实践中是可行的,但我构建了两次相同的配置


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

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

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

如果我不明白您的意思,我所知道的是,安装程序将需要它来进行依赖项注入,或者您不能使用它,因此,您可以使用服务集合的扩展来完成您想要的配置,您可以在容器中获得设置

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

publicstaticvoidmain(字符串[]args)
{
//...
var configuration=new ConfigurationBuilder()
.AddenEnvironmentVariables()
.AddCommandLine(args)
.AddJsonFile(“appsettings.json”)
.Build();
//对配置执行一些有用的操作。。。
var host=host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(生成器=>
{
builder.Sources.Clear();
builder.AddConfiguration(配置);
})
.ConfigureWebHostDefaults(webBuilder=>
{
webBuilder.UseStartup();
})
.Build();
//...
}

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

或者,如果您无法访问您的配置,或者您得到
System.NullReferenceException:“对象引用未设置为对象的实例”。
错误,这意味着
IHostBuilder
无法在其基本路径中看到json文件

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

  • 将“构建操作”设置为“内容”
  • 将“复制到输出目录”设置为“更新时复制”

  • 恐怕不行,因为您在初始化主机之前无法获得配置。@XingZou事实上,我可以在设置主机之前设置配置,唯一的问题是,我无法再次重用该配置,这迫使我为初始化配置付出代价。有些值在应用程序宿主和其他部分之间共享。一个具体的例子是在主机之前配置一个记录器,以便我可以记录启动错误。记录器记录到应用程序数据库,因此我希望记录器和应用程序在一个配置文件中使用一个连接字符串。尽管我有一个附加问题,但这是最好的答案,因为我还在ConfigureAppConfiguration中使用了hostContext,这在上述示例中不可用。我使用hostContext获取HostingEnvironment。如何从
    启动
    访问配置?再次调用
    ConfigureConfigurationBuilder
    ?您的启动类可以通过DIPerfect在构造函数中接收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();
    
        //...
    }