2017-09-02 59 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