.NET Core控制台应用程序,如何为每个环境配置appSettings?

时间:2016-09-19 12:46:44

标签: c# console-application .net-core

我有一个.NET Core 1.0.0控制台应用程序和两个环境。我需要能够根据我在运行时设置的环境变量使用appSettings.dev.jsonappSettings.test.json。对于ASP.NET Core Web应用程序来说,这似乎非常简单,通过依赖注入和IHostingEnvironment以及EnvironmentName env。变量,但是我应该如何为控制台应用程序连接(除了编写我自己使用Microsoft.Framework.Configuration.EnvironmentVariables的自定义代码)?

谢谢。

9 个答案:

答案 0 :(得分:50)

我们在.netcore控制台应用中执行此操作。这里的关键是在项目中包含正确的依赖项即(可能不是全部,根据您的需要进行检查)并复制以输出appSetting.json作为你的 buildoptions

  {
       "Microsoft.Extensions.Configuration": "1.0.0",
       "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
       "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
       "Microsoft.Extensions.Configuration.Json": "1.0.0",
  } 
    "buildOptions": {
    "emitEntryPoint": true,
    "copyToOutput": {
       "include": [
       "appsettings*.json",
       "App*.config"
                 ]
          }
},

  using Microsoft.Extensions.Configuration;
  namespace MyApp
  {
    public static void Main(string[] args)
    {
        var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");


        var builder = new ConfigurationBuilder()
            .AddJsonFile($"appsettings.json", true, true)
            .AddJsonFile($"appsettings.{environmentName}.json", true, true)
            .AddEnvironmentVariables();
        var configuration = builder.Build();
        var myConnString= configuration.GetConnectionString("SQLConn");
    }

}

答案 1 :(得分:4)

您应该使用两个IHostingEnvironment接口。一种用于ASP.NET Core应用程序,另一种用于.NET Core控制台应用程序。您可以同时使用以下代码示例:

using System;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting.Internal;

namespace MyApplication.Common
{
    public static class ConfigurationFactory
    {
        /// <summary>
        /// Use for ASP.NET Core Web applications.
        /// </summary>
        /// <param name="config"></param>
        /// <param name="env"></param>
        /// <returns></returns>
        public static IConfigurationBuilder Configure(IConfigurationBuilder config, IHostingEnvironment env)
        {
            return Configure(config, env.EnvironmentName);
        }

        /// <summary>
        /// Use for .NET Core Console applications.
        /// </summary>
        /// <param name="config"></param>
        /// <param name="env"></param>
        /// <returns></returns>
        private static IConfigurationBuilder Configure(IConfigurationBuilder config, Microsoft.Extensions.Hosting.IHostingEnvironment env)
        {
            return Configure(config, env.EnvironmentName);
        }

        private static IConfigurationBuilder Configure(IConfigurationBuilder config, string environmentName)
        {
            return config
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables();
        }

        /// <summary>
        /// Use for .NET Core Console applications.
        /// </summary>
        /// <returns></returns>
        public static IConfiguration CreateConfiguration()
        {
            var env = new HostingEnvironment
            {
                EnvironmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"),
                ApplicationName = AppDomain.CurrentDomain.FriendlyName,
                ContentRootPath = AppDomain.CurrentDomain.BaseDirectory,
                ContentRootFileProvider = new PhysicalFileProvider(AppDomain.CurrentDomain.BaseDirectory)
            };

            var config = new ConfigurationBuilder();
            var configured = Configure(config, env);
            return configured.Build();
        }
    }
}

答案 2 :(得分:3)

您可以为ASP.Net Core环境变量(ASPNETCORE_ENVIRONMENT)执行此操作: -

using Microsoft.AspNetCore.Hosting;
using System;

public class Program {
    private static string HostingEnvironment => Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
    private static bool IsEnvironment(string environmentName) => HostingEnvironment?.ToLower() == environmentName?.ToLower() && null != environmentName;

    private static bool Development => IsEnvironment(EnvironmentName.Development);
    private static bool Production => IsEnvironment(EnvironmentName.Production);
    private static bool Staging => IsEnvironment(EnvironmentName.Staging);

    public static void Main(string[] args) { // Your code here }
}

然后你可以简单地使用属性

    public static void Main(string[] args) {
        if (Development){
            // Blow up the planet
        }
    }

答案 3 :(得分:3)

对于那些使用.NET Core版本2.1.0+和Microsoft.Extensions.Hosting托管控制台应用程序的用户,您可以使用以下代码(根据Feiyu Zhou的answer在另一个线程中):

var hostBuilder = new HostBuilder()
    .ConfigureHostConfiguration(config =>
    {
        if (args != null)
        {
            // enviroment from command line
            // e.g.: dotnet run --environment "Staging"
            config.AddCommandLine(args);
        }
    })
    .ConfigureAppConfiguration((context, builder) =>
    {
        builder.SetBasePath(AppContext.BaseDirectory)
            .AddJsonFile("appsettings.json", optional: false)
            .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true);
    })

答案 4 :(得分:1)

从 Net Core 3.1++ 开始,通用主机类 Microsoft.Extensions.Hosting.Host 使用 DOTNET_ENVIRONMENT 环境变量而不是 ASPNETCORE_ENVIRONMENT。

在项目调试设置中设置 DOTNET_ENVIRONMENT="Development" 无需任何额外编码即可工作。

或者您可以像这样添加自己的前缀:

// works for WPF but should work similar for Console Apps
public partial class App : Application
{
    private readonly IHost _host;

    public App()
    {
        _host = Host.CreateDefaultBuilder()
            .ConfigureHostConfiguration(configHost => {
                configHost.AddEnvironmentVariables(prefix: "PREFIX_");
            })
            .ConfigureServices((context, services) =>
            {
                ConfigureServices(context.Configuration, services);
            })
            .Build();
    }

    private void ConfigureServices(
        IConfiguration configuration,
        IServiceCollection services)
    {
       // ...
    }

    // ...
}

答案 5 :(得分:0)

对于dotnet 2.x核心控制台应用程序来说,是这样的:

        using Microsoft.Extensions.Configuration;
        using Microsoft.Extensions.DependencyInjection;
        using Microsoft.Extensions.Logging;

        [...]
        var configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddEnvironmentVariables()
            .Build();
        var serviceProvider = new ServiceCollection()
            .AddLogging(options => options.AddConfiguration(configuration).AddConsole())
            .AddSingleton<IConfiguration>(configuration)
            .AddSingleton<SomeService>()
            .BuildServiceProvider();
        [...]
        await serviceProvider.GetService<SomeService>().Start();

您可以在SomeService中注入ILoggerFactory和IConfiguration。

答案 6 :(得分:0)

如果像我一样,您只是尝试为发布和开发模式使用其他配置文件,只需在文件的属性窗口中添加一个appsettings.Development.json文件并将CopyToOutputDirectory设置设置为true。

现在,要根据构建配置访问文件,可以使用#if DEBUG preprocessor directive

这是一个例子:

static void Main(string[] args)
{

#if DEBUG
    var builder = new ConfigurationBuilder()
            .AddJsonFile($"appsettings.Development.json", true, true);
#else
    var builder = new ConfigurationBuilder()
            .AddJsonFile($"appsettings.json", true, true);
#endif

    var configuration = builder.Build();

    // ... use configuration
}

答案 7 :(得分:0)

这些环境似乎对大多数人都有效,但是我完全不同意所有环境管理。运行时或目标系统都知道它是什么。作为开发人员或部署机制的只有您自己知道目标系统是什么。

每个人都在谈论ASPNETCORE_ENVIRONMENT变量,甚至像这里的https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-3.0这样的官方文档。但是实际上,有人必须将系统明确定义为生产系统,例如,只需手动设置一次ASPNETCORE_ENVIRONMENT。您是否真的要假设并依靠它在您使用的每个环境中都已设置?不,你不能。如果必须将控制台应用程序部署到没有网站运行的批处理服务器上怎么办? ASPNETCORE_ENVIRONMENT不可用。如果您需要仅使用kestrel来部署和运行不带IIS的.net核心webapi,该怎么办?没有web.config,没有环境变量。您是否希望管理员/运营团队为您的控制台应用程序设置此误导性变量?在这种情况下,我看到很多项目的每个项目都有这样的应用程序设置:

appsettings.json
appsettings.development.json
appsettings.test.json
appsettings.uat.json
appsettings.staging.json
appsettings.production.json

请记住,默认情况下,这些文件中的每个文件都将被发布,也将被部署到目标系统。乍一看,让环境“决定”应该使用哪个配置似乎很容易。但是您具有配置,并且还可能在不适合它的系统上部署了凭据。

结论

我建议使用appsettings.json + appsettings.release.json。第一个仅适用于开发人员。更改它,然后随心所欲地玩它。最后一个是准备进行部署(过程)的有效配置。在开始部署之前,请转换配置以使其可用于目标系统。而已。无需依赖目标计算机上的设置,无需混乱的配置。即使服务器发生快速变化(例如扩展规模,VM,云等),也可以完全控制您的应用程序

我感谢建设性的反馈意见:-)

答案 8 :(得分:0)

适用于 .NetCore 3.1 和使用 .CreateDefaultBuilder(args) 扩展的任何人。只需将 -environment "Development" 添加到调试设置中的命令行参数即可。完成。