为什么 Startup 的 IConfigurationRoot 为空?
Why Startup's IConfigurationRoot is null?
我正在尝试将命令行参数传递给 Startup
class。按照 示例,我修改了我的 Program
class,它看起来像这样:
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("generalsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.AddCommandLine(args);
var config = builder.Build();
var host = new WebHostBuilder()
.UseUrls("http://*:5000")
.UseConfiguration(config)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
generalsettings.json
包含以下数据:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
因此我注释掉了默认的 Startup
class' 构造函数。然后我注意到那是分配 IConfigurationRoot Configuration
的地方,因此,当我尝试从 ConfigureServices
使用它时,它是空的。我正在尝试使用(我认为)内置于 Program
的 Main
中的配置。我在这里错过了什么?
更新
要说清楚:我正在尝试在 Startup
class.
中使用 args
事实证明,在 GitHub Aspnet hosting repo issues area 中对这类事情进行了大量讨论。 GitHub 存储库始终是查看此类有趣问题的好地方。
给大家总结一下,不要在Program.Main里设置IConfigurationRoot,在Startup里设置。您可以将命令行参数从 Program.cs 传递给 Startup 构造函数,如下所示:
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.ConfigureServices(services => services
.AddSingleton(new ConsoleArgs(args))
)
.Build();
host.Run();
}
其中 ConsoleArgs 是持有者 class 你可以自己创建如下所示:
public class ConsoleArgs
{
public ConsoleArgs(string[] args)
{
Args = args;
}
public string[] Args { get; }
}
很明显,配置一个ConsoleArgsservice是关键。这将允许它被注入到 Startup 构造函数中。然后你的 Startup class 构造函数看起来像
public Startup(IHostingEnvironment env, ConsoleArgs args)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("generalsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.AddCommandLine(args.Args);
var config = builder.Build();
}
这里的模式是"configure you hosting environment Program, configure you application in Startup"
我正在尝试将命令行参数传递给 Startup
class。按照 Program
class,它看起来像这样:
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("generalsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.AddCommandLine(args);
var config = builder.Build();
var host = new WebHostBuilder()
.UseUrls("http://*:5000")
.UseConfiguration(config)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
generalsettings.json
包含以下数据:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
因此我注释掉了默认的 Startup
class' 构造函数。然后我注意到那是分配 IConfigurationRoot Configuration
的地方,因此,当我尝试从 ConfigureServices
使用它时,它是空的。我正在尝试使用(我认为)内置于 Program
的 Main
中的配置。我在这里错过了什么?
更新
要说清楚:我正在尝试在 Startup
class.
args
事实证明,在 GitHub Aspnet hosting repo issues area 中对这类事情进行了大量讨论。 GitHub 存储库始终是查看此类有趣问题的好地方。
给大家总结一下,不要在Program.Main里设置IConfigurationRoot,在Startup里设置。您可以将命令行参数从 Program.cs 传递给 Startup 构造函数,如下所示:
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.ConfigureServices(services => services
.AddSingleton(new ConsoleArgs(args))
)
.Build();
host.Run();
}
其中 ConsoleArgs 是持有者 class 你可以自己创建如下所示:
public class ConsoleArgs
{
public ConsoleArgs(string[] args)
{
Args = args;
}
public string[] Args { get; }
}
很明显,配置一个ConsoleArgsservice是关键。这将允许它被注入到 Startup 构造函数中。然后你的 Startup class 构造函数看起来像
public Startup(IHostingEnvironment env, ConsoleArgs args)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("generalsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.AddCommandLine(args.Args);
var config = builder.Build();
}
这里的模式是"configure you hosting environment Program, configure you application in Startup"