在构建WebHost之前访问托管环境

时间:2017-09-02 10:43:37

标签: asp.net-core .net-core asp.net-core-2.0 .net-core-2.0

在我的Program.cs主要方法中,我想阅读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();
}

在构建IHostingEnvironment之前,是否有更简单的方法来访问WebHost

3 个答案:

答案 0 :(得分:2)

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操作系统中很敏感,有时最好使用$"appsettings.{envName.ToLower()}.json"代替。

答案 1 :(得分:2)

我想做类似的事情。我想根据环境设置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();
    }
}

答案 2 :(得分:1)

在.Net Core 2.0中,您可以这样做

var webHostBuilder = WebHost.CreateDefaultBuilder(args);
var environment = webHostBuilder.GetSetting("environment");