2017-09-02 18 views
0

在我的Program.cs主要方法中,我想讀取user secrets,配置一個記錄器,然後構建WebHost在構建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之前?

回答

1

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"代替。

+0

Thanks @Set。我已經使用了這個版本來獲取bootstraping與用戶祕密的工作,但我只是想知道是否有另一種重新設計過程的方式更容易。配置主機的新方法非常好,因此我認爲將其拆毀並讓自己的方法執行主機擴展方法所做的相同的事情是一種恥辱。感謝'envName.ToLower()'提示。 – leon

1

我想做類似的事情。我想根據環境設置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(); 
    } 
} 
+0

謝謝@GlennSills。我認爲這是一個方便的方法,但對於我的情況,我需要在構建虛擬主機之前創建主機環境。 – leon