【问题标题】:ASP.NET Core configuration for .NET Core console application.NET Core 控制台应用程序的 ASP.NET Core 配置
【发布时间】:2016-11-02 01:21:29
【问题描述】:

ASP.NET Core 支持一个新的配置系统,如下所示: https://docs.asp.net/en/latest/fundamentals/configuration.html

.NET Core 控制台应用程序是否也支持此模型?

如果不是之前的app.configConfigurationManager 模型的替代品是什么?

【问题讨论】:

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


    【解决方案1】:

    对于 .NET Core 2.0 控制台应用程序,我执行了以下操作:

    1. 在项目的根目录下新建一个名为appsettings.json的文件(文件名可以任意)
    2. 将我的特定设置作为 json 添加到该文件中。例如:
    {
      "myKey1" :  "my test value 1", 
      "myKey2" :  "my test value 2", 
      "foo" :  "bar" 
    }
    
    1. 配置在构建项目时将文件复制到输出目录(在 VS -> 解决方案资源管理器 -> 右键单击​​文件 -> 选择“属性” -> 高级 -> 复制到输出目录 -> 选择“始终复制”)

    2. 在我的项目中安装以下 nuget 包:

      • Microsoft.Extensions.Configuration.Json
    3. 将以下内容添加到 Program.cs(或 Main() 所在的任何位置):

      static void Main(string[] args)
      {
          var builder = new ConfigurationBuilder()
              .SetBasePath(Directory.GetCurrentDirectory())
              .AddJsonFile("appsettings.json");
      
          var configuration = builder.Build();
      
          // rest of code...
      }
      
    4. 然后使用以下任一方式读取值:

      string myKey1 = configuration["myKey1"];
      Console.WriteLine(myKey1);
      
      string foo = configuration.GetSection("foo").Value;
      Console.WriteLine(foo);
      

    更多信息:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration?tabs=basicconfiguration#simple-configuration

    【讨论】:

    • 我注意到微软在他们的示例中没有使用 IConfigurationRoot,而是使用 IConfiguration。
    • IConfigurationRoot is still available in .NET Core 2.0。它继承自IConfiguration,但它被认为是a derived case of it that's not commonly used。无论如何,代码示例已更新为不包含它并避免任何混淆。
    • 2 注释:在第 4 点,您只需要 Microsoft.Extensions.Configuration.Json... 默认情况下它将包括其他 2 个。第二:如果你想将一个部分加载到一个对象中,知道: var options = new FooOptions(); ConfigurationBinder.Bind(configuration.GetSection("foo"), options);您将需要 Microsoft.Extensions.Options.ConfigurationExtensions
    • public class FooOptions{ public string myKey1 {get; set;} 公共字符串 myKey2 {get;set;}}
    • 工具 > NuGet 包管理器 > 包管理器控制台 .. .. 安装包 Microsoft.Extensions.Configuration .. 安装包 Microsoft.Extensions.Configuration.FileExtensions .. 安装包 Microsoft.Extensions。配置.Json
    【解决方案2】:

    您可以使用此代码 sn-p。它包括配置和 DI。

    public class Program
    {
        public static ILoggerFactory LoggerFactory;
        public static IConfigurationRoot Configuration;
    
        public static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
    
            string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
    
            if (String.IsNullOrWhiteSpace(environment))
                throw new ArgumentNullException("Environment not found in ASPNETCORE_ENVIRONMENT");
    
            Console.WriteLine("Environment: {0}", environment);
    
            var services = new ServiceCollection();
    
            // Set up configuration sources.
            var builder = new ConfigurationBuilder()
                .SetBasePath(Path.Combine(AppContext.BaseDirectory))
                .AddJsonFile("appsettings.json", optional: true);
            if (environment == "Development")
            {
    
                builder
                    .AddJsonFile(
                        Path.Combine(AppContext.BaseDirectory, string.Format("..{0}..{0}..{0}", Path.DirectorySeparatorChar), $"appsettings.{environment}.json"),
                        optional: true
                    );
            }
            else
            {
                builder
                    .AddJsonFile($"appsettings.{environment}.json", optional: false);
            }
    
            Configuration = builder.Build();
    
            LoggerFactory = new LoggerFactory()
                .AddConsole(Configuration.GetSection("Logging"))
                .AddDebug();
    
            services
                .AddEntityFrameworkNpgsql()
                .AddDbContext<FmDataContext>(o => o.UseNpgsql(connectionString), ServiceLifetime.Transient);
    
            services.AddTransient<IPackageFileService, PackageFileServiceImpl>();
    
            var serviceProvider = services.BuildServiceProvider();
    
            var packageFileService = serviceProvider.GetRequiredService<IPackageFileService>();
    
            ............
        }
    }
    

    哦,别忘了在project.json中添加

    {
      "version": "1.0.0-*",
      "buildOptions": {
        "emitEntryPoint": true,
        "copyToOutput": {
          "includeFiles": [
            "appsettings.json",
            "appsettings.Integration.json",
            "appsettings.Production.json",
            "appsettings.Staging.json"
          ]
        }
      },
    
      "publishOptions": {
        "copyToOutput": [
          "appsettings.json",
          "appsettings.Integration.json",
          "appsettings.Production.json",
          "appsettings.Staging.json"
        ]
      },
    ...
    }
    

    【讨论】:

    • 这个答案并不理想。使用Directory.GetCurrentDirectory() 而不是AppContext.BaseDirectory。之后应该不需要破解。
    • 或者在 Visual Studio 中将 JSON 文件的“复制到输出目录”属性设置为“如果较新则复制”。
    • 似乎没有SetBasePath 方法,除非您添加Microsoft.Extensions.Configuration.FileExtensions。没有AddJsonFile 没有Microsoft.Extensions.Configuration.Json
    • string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); 这太业余了。您可以通过设置全局变量来搞砸其他应用程序。你不能同时运行 dev 和 prod。使用 netcore 后 MS 质量大幅下降
    • 在 docker 中拥有自己环境的微服务改变了普通应用程序必须编写的方法。这就是现实。
    【解决方案3】:

    如果您使用Microsoft.Extensions.Hosting(版本 2.1.0+)来托管您的控制台应用程序和 asp.net 核心应用程序,则您的所有配置都将使用HostBuilderConfigureAppConfigurationConfigureHostConfiguration 方法注入。这是关于如何添加appsettings.json 和环境变量的演示:

        var hostBuilder = new HostBuilder()
            .ConfigureHostConfiguration(config =>
            {
                config.AddEnvironmentVariables();
    
                if (args != null)
                {
                    // enviroment from command line
                    // e.g.: dotnet run --environment "Staging"
                    config.AddCommandLine(args);
                }
            })
            .ConfigureAppConfiguration((context, builder) =>
            {
                var env = context.HostingEnvironment;
                builder.SetBasePath(AppContext.BaseDirectory)
                .AddJsonFile("appsettings.json", optional: false)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                // Override config by env, using like Logging:Level or Logging__Level
                .AddEnvironmentVariables();
    
            })
            ... // add others, logging, services
            //;
    

    为了编译上面的代码,你需要添加这些包:

    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="2.1.0" />
    

    【讨论】:

    • 环境是如何确定的?如果我在launchSettings 中创建配置文件,它实际上设置了ASPNETCORE_ENVIRONMENT,但是context.HostingEnvironment.EnvironmentName 没有正确设置
    • 你应该使用环境作为关键,检查这个代码:github.com/aspnet/Hosting/blob/dev/src/…
    • @FeiyuZhou 这是一个死链接
    • new HostBuilder() 之后,这个解决方案的全部 不是多余的吗? HostBuilder 不都是在内部做的吗?
    • @Auspex 这取决于您如何定义控制台应用程序。如果您需要定义自定义配置,那么您应该这样设置。这是 dotnet core 3.0 的文档:docs.microsoft.com/en-us/aspnet/core/fundamentals/host/…
    【解决方案4】:

    我错了。您可以在 netcore 控制台应用程序中使用新的 ConfigurationBuilder

    有关示例,请参阅 https://docs.asp.net/en/latest/fundamentals/configuration.html

    但是,只有 aspnet 核心具有开箱即用的依赖注入功能,因此您无法拥有强类型配置设置并使用 IOptions 自动注入它们。

    【讨论】:

    • 这个答案是有效的,但它应该包含必要的代码,因此不赞成。
    • 您只需添加包:Microsoft.Extensions.Options 并致电service.AddOptions();
    • 整个(很长的)链接页面似乎与 ASP.NET 相关,每个示例中都提到了“WebHost”。在找到链接页面并思考“好的,那是 ASP.NET,控制台应用程序怎么样”后,我遇到了这个 SO 问题。
    • 这有点奇怪,@mackenir,因为在 3.0 中它都被重构了,所以它只是 Host!对 WebHost 本身的唯一引用是指向您的 2.2 文档。他们本可以更清楚一点,示例中的 ConfigureWebHostDefaults() 调用是可选的,并且仅适用于 Web 应用程序。
    【解决方案5】:

    在 .Net Core 3.1 上,我们只需要这样做:

    static void Main(string[] args)
    {
      var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
    }
    

    使用 SeriLog 将如下所示:

    using Microsoft.Extensions.Configuration;
    using Serilog;
    using System;
    
    
    namespace yournamespace
    {
        class Program
        {
    
            static void Main(string[] args)
            {
                var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
                Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
    
                try
                {
                    Log.Information("Starting Program.");
                }
                catch (Exception ex)
                {
                    Log.Fatal(ex, "Program terminated unexpectedly.");
                    return;
                }
                finally
                {
                    Log.CloseAndFlush();
                }
            }
        }
    }
    

    每天生成一个文件的 Serilog appsetings.json 部分如下所示:

      "Serilog": {
        "MinimumLevel": {
          "Default": "Information",
          "Override": {
            "Microsoft": "Warning",
            "System": "Warning"
          }
        },
        "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
        "WriteTo": [
          {
            "Name": "File",
            "Args": {
              "path": "C:\\Logs\\Program.json",
              "rollingInterval": "Day",
              "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact"
            }
          }
        ]
      }
    

    【讨论】:

    • 在尝试了所有网络上的所有语法之后,你的语法对我有用,而且非常简单。
    【解决方案6】:

    如果您使用.netcore 3.1 最简单的方法是使用新的配置系统调用静态类HostCreateDefaultBuilder 方法并配置应用程序

    public class Program
    {
        public static void Main(string[] args)
        {
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((context, config) =>
                {
                    IHostEnvironment env = context.HostingEnvironment;
                    config.AddEnvironmentVariables()
                        // copy configuration files to output directory
                        .AddJsonFile("appsettings.json")
                        // default prefix for environment variables is DOTNET_
                        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                        .AddCommandLine(args);
                })
                .ConfigureServices(services =>
                {
                    services.AddSingleton<IHostedService, MySimpleService>();
                })
                .Build()
                .Run();
        }
    }
    
    class MySimpleService : IHostedService
    {
        public Task StartAsync(CancellationToken cancellationToken)
        {
            Console.WriteLine("StartAsync");
            return Task.CompletedTask;
        }
    
        public Task StopAsync(CancellationToken cancellationToken)
        {
            Console.WriteLine("StopAsync");
            return Task.CompletedTask;
        }
    }
    

    您需要为文件 appsettings.jsonappsettings.{environment}.json 设置 Copy to Output Directory = 'Copy if newer' 您还可以设置环境变量 {prefix}ENVIRONMENT(默认前缀是 DOTNET)以允许选择特定的配置参数。

    .csproj 文件:

    <PropertyGroup>
      <OutputType>Exe</OutputType>
      <TargetFramework>netcoreapp3.1</TargetFramework>
      <RootNamespace>ConsoleApplication3</RootNamespace>
      <AssemblyName>ConsoleApplication3</AssemblyName>
    </PropertyGroup>
    
    <ItemGroup>
      <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.7" />
      <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.7" />
    </ItemGroup>
    
    <ItemGroup>
      <None Update="appsettings.Development.json">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </None>
      <None Update="appsettings.json">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </None>
    </ItemGroup>
    

    更多详情.NET Generic Host

    【讨论】:

    • 哦,最后感谢您为我指明了正确的方向!区分 ASP.NET.CORE 和 DOTNET.CORE 非常重要 如果使用 .NET Core 应用程序(不是 asp web 的东西,而是用于微服务的控制台或 windows/linux 服务),您必须将调试环境变量设置为 DOTNET_ENVIRONMENT。然后它将与 context.HostingEnviornment.EnviornmentName 一起使用。
    【解决方案7】:

    对于 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。

    【讨论】:

      【解决方案8】:

      安装这些软件包:

      • Microsoft.Extensions.Configuration
      • Microsoft.Extensions.Configuration.Binder
      • Microsoft.Extensions.Configuration.EnvironmentVariables
      • Microsoft.Extensions.Configuration.FileExtensions
      • Microsoft.Extensions.Configuration.Json

      代码:

      static void Main(string[] args)
          {
              var environmentName = Environment.GetEnvironmentVariable("ENVIRONMENT");
              Console.WriteLine("ENVIRONMENT: " + environmentName);
      
              var builder = new ConfigurationBuilder()
                 .SetBasePath(Directory.GetCurrentDirectory())
                 .AddJsonFile("appsettings.json", false)
                 .AddJsonFile($"appsettings.{environmentName}.json", true)
                 .AddEnvironmentVariables();
      
              IConfigurationRoot configuration = builder.Build();
              var mySettingsConfig = configuration.Get<MySettingsConfig>();
      
              Console.WriteLine("URL: " + mySettingsConfig.Url);
              Console.WriteLine("NAME: " + mySettingsConfig.Name);
      
              Console.ReadKey();
          }
      

      MySettingsConfig 类:

      public class MySettingsConfig
      {
          public string Url { get; set; }
          public string Name { get; set; }
      }
      

      您的应用设置可以像这样简单:

      此外,如果更新,请将 appsettings 文件设置为 Content / Copy:

      【讨论】:

        【解决方案9】:

        您可以为此使用LiteWare.Configuration 库。它与 .NET Framework 原始 ConfigurationManager 非常相似,适用于 .NET Core/Standard。代码方面,你最终会得到类似的东西:

        string cacheDirectory = ConfigurationManager.AppSettings.GetValue<string>("CacheDirectory");
        ulong cacheFileSize = ConfigurationManager.AppSettings.GetValue<ulong>("CacheFileSize");
        

        免责声明:我是 LiteWare.Configuration 的作者。

        【讨论】:

          【解决方案10】:

          只是堆积...类似于周飞宇的帖子。这里我添加机器名称。

          public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                  WebHost.CreateDefaultBuilder(args)
                    .ConfigureAppConfiguration((context, builder) =>
                    {
                      var env = context.HostingEnvironment;
                      var hostname = Environment.MachineName;
                      builder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
                        .AddJsonFile($"appsettings.{hostname}.json", optional: true, reloadOnChange: true);
                      builder.AddEnvironmentVariables();
                      if (args != null)
                      {
                        builder.AddCommandLine(args);
                      }
                    })
                  .UseStartup<Startup>();
            }
          

          【讨论】:

            【解决方案11】:

            其他解决方案有效,但如果您想在其他服务中注入 IConfigurationRoot 则不行。我就是这样做的:

            然后安装Microsoft.Extensions.Configuration.Json

            static void Main(string[] args)
            {
                var serviceProvider = new ServiceCollection()
                    .AddSingleton(_ =>
                        new ConfigurationBuilder()
                            .SetBasePath(Path.Combine(AppContext.BaseDirectory))
                            .AddJsonFile("appsettings.json", optional: true)
                            .Build())
                    .BuildServiceProvider();
            
                 // Rest of code ...
            }
            

            并在其他服务中注入或使用

            serviceProvider.GetService<IConfigurationRoot>()
            

            【讨论】:

              猜你喜欢
              • 2016-12-07
              • 1970-01-01
              • 1970-01-01
              • 2018-09-12
              • 2018-02-16
              • 1970-01-01
              • 2020-07-14
              • 2017-08-21
              • 2023-04-10
              相关资源
              最近更新 更多