在构建 WebHost 之前访问托管环境
Access hosting environment before building WebHost
在我的 Program.cs
Main 方法中,我想阅读 user secrets,配置记录器,然后构建 WebHost
.
public static Main(string[] args)
{
string instrumentationKey = null; // read from UserSecrets
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.ApplicationInsightsEvents(instrumentationKey)
.CreateLogger();
BuildWebHost(args).Run();
}
我可以通过构建自己的配置来获取配置,但我很快就在尝试访问托管环境属性时陷入混乱:
public static Main(string[] args)
{
var envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
var configBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{envName}.json", optional: true, reloadOnChange: true);
// Add user secrets if env.IsDevelopment().
// Normally this convenience IsDevelopment method would be available
// from HostingEnvironmentExtensions I'm using a private method here.
if (IsDevelopment(envName))
{
string assemblyName = "<I would like the hosting environment here too>"; // e.g env.ApplicationName
var appAssembly = Assembly.Load(new AssemblyName(assemblyName));
if (appAssembly != null)
{
configBuilder.AddUserSecrets(appAssembly, optional: true); // finally, user secrets \o/
}
}
var config = configBuilder.Build();
string instrumentationKey = config["MySecretFromUserSecretsIfDevEnv"];
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.ApplicationInsightsEvents(instrumentationKey) // that.. escallated quickly
.CreateLogger();
// webHostBuilder.UseConfiguration(config) later on..
BuildWebHost(args, config).Run();
}
在构建 WebHost
之前,是否有更简单的方法访问 IHostingEnvironment
?
在 main
方法中,您无法在构建 WebHost 之前获取 IHostingEnvironment
实例,因为尚未创建托管。而且您无法正确创建新的有效实例,如 it must be initialized using WebHostOptions`.
对于应用程序名称,您可以使用 Assembly.GetEntryAssembly()?.GetName().Name
对于环境名称,请使用您当前所做的(我假设您的 IsDevelopment() 方法中使用了类似这样的内容):
var environmentName = System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
bool isDevelopment = string.Equals(
"Development",
environmentName,
StringComparison.OrdinalIgnoreCase);
看,像 IHostingEnvironment.IsDevelopment()
这样的方法是 extension methods that simply do string comparison internally:
public static bool IsDevelopment(this IHostingEnvironment hostingEnvironment)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}
return hostingEnvironment.IsEnvironment(EnvironmentName.Development);
}
public static bool IsEnvironment(
this IHostingEnvironment hostingEnvironment,
string environmentName)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}
return string.Equals(
hostingEnvironment.EnvironmentName,
environmentName,
StringComparison.OrdinalIgnoreCase);
}
关于 AddJsonFile
的注意事项:由于文件名在 Unix OS 中是敏感的,有时最好使用 $"appsettings.{envName.ToLower()}.json"
而不是
我想做类似的事情。我想根据环境设置 Kestrel 监听选项。我只是在配置应用程序配置时将 IHostingEnvironment 保存到局部变量。稍后我使用该变量根据环境做出决定。您应该能够遵循此模式来实现您的目标。
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
IHostingEnvironment env = null;
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((hostingContext, config) =>
{
env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.UseKestrel(options =>
{
if (env.IsDevelopment())
{
options.Listen(IPAddress.Loopback, 44321, listenOptions =>
{
listenOptions.UseHttps("testcert.pfx", "ordinary");
});
}
else
{
options.Listen(IPAddress.Loopback, 5000);
}
})
.Build();
}
}
在 .Net Core 2.0 中你可以这样做
var webHostBuilder = WebHost.CreateDefaultBuilder(args);
var environment = webHostBuilder.GetSetting("environment");
在我的 Program.cs
Main 方法中,我想阅读 user secrets,配置记录器,然后构建 WebHost
.
public static Main(string[] args)
{
string instrumentationKey = null; // read from UserSecrets
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.ApplicationInsightsEvents(instrumentationKey)
.CreateLogger();
BuildWebHost(args).Run();
}
我可以通过构建自己的配置来获取配置,但我很快就在尝试访问托管环境属性时陷入混乱:
public static Main(string[] args)
{
var envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
var configBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{envName}.json", optional: true, reloadOnChange: true);
// Add user secrets if env.IsDevelopment().
// Normally this convenience IsDevelopment method would be available
// from HostingEnvironmentExtensions I'm using a private method here.
if (IsDevelopment(envName))
{
string assemblyName = "<I would like the hosting environment here too>"; // e.g env.ApplicationName
var appAssembly = Assembly.Load(new AssemblyName(assemblyName));
if (appAssembly != null)
{
configBuilder.AddUserSecrets(appAssembly, optional: true); // finally, user secrets \o/
}
}
var config = configBuilder.Build();
string instrumentationKey = config["MySecretFromUserSecretsIfDevEnv"];
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.ApplicationInsightsEvents(instrumentationKey) // that.. escallated quickly
.CreateLogger();
// webHostBuilder.UseConfiguration(config) later on..
BuildWebHost(args, config).Run();
}
在构建 WebHost
之前,是否有更简单的方法访问 IHostingEnvironment
?
在 main
方法中,您无法在构建 WebHost 之前获取 IHostingEnvironment
实例,因为尚未创建托管。而且您无法正确创建新的有效实例,如 it must be initialized using WebHostOptions`.
对于应用程序名称,您可以使用 Assembly.GetEntryAssembly()?.GetName().Name
对于环境名称,请使用您当前所做的(我假设您的 IsDevelopment() 方法中使用了类似这样的内容):
var environmentName = System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
bool isDevelopment = string.Equals(
"Development",
environmentName,
StringComparison.OrdinalIgnoreCase);
看,像 IHostingEnvironment.IsDevelopment()
这样的方法是 extension methods that simply do string comparison internally:
public static bool IsDevelopment(this IHostingEnvironment hostingEnvironment)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}
return hostingEnvironment.IsEnvironment(EnvironmentName.Development);
}
public static bool IsEnvironment(
this IHostingEnvironment hostingEnvironment,
string environmentName)
{
if (hostingEnvironment == null)
{
throw new ArgumentNullException(nameof(hostingEnvironment));
}
return string.Equals(
hostingEnvironment.EnvironmentName,
environmentName,
StringComparison.OrdinalIgnoreCase);
}
关于 AddJsonFile
的注意事项:由于文件名在 Unix OS 中是敏感的,有时最好使用 $"appsettings.{envName.ToLower()}.json"
而不是
我想做类似的事情。我想根据环境设置 Kestrel 监听选项。我只是在配置应用程序配置时将 IHostingEnvironment 保存到局部变量。稍后我使用该变量根据环境做出决定。您应该能够遵循此模式来实现您的目标。
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
IHostingEnvironment env = null;
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((hostingContext, config) =>
{
env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.UseKestrel(options =>
{
if (env.IsDevelopment())
{
options.Listen(IPAddress.Loopback, 44321, listenOptions =>
{
listenOptions.UseHttps("testcert.pfx", "ordinary");
});
}
else
{
options.Listen(IPAddress.Loopback, 5000);
}
})
.Build();
}
}
在 .Net Core 2.0 中你可以这样做
var webHostBuilder = WebHost.CreateDefaultBuilder(args);
var environment = webHostBuilder.GetSetting("environment");