Конфигурация ASP.NET Core для консольного приложения .NET Core

137

ASP.NET Core поддерживает новую систему конфигурации, как показано здесь: https://docs.asp.net/en/latest/fundamentals/configuration.html

Поддерживается ли эта модель также в консольных приложениях .NET Core?

Если нет, то какая альтернатива предыдущей app.configи ConfigurationManagerмодели?

kimsagro
источник

Ответы:

76

Вы можете использовать этот фрагмент кода. Он включает в себя конфигурацию и 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"
    ]
  },
...
}
aligin
источник
12
Этот ответ не идеален. Используйте Directory.GetCurrentDirectory()вместо AppContext.BaseDirectory. После этого не должно быть необходимости во взломе.
Матиас
1
Или установите для свойства «Копировать в выходной каталог» значение «Копировать, если новее» в Visual Studio для файлов JSON.
BuddhiP
Чтобы базовый каталог работал в Интернете, консоли и Winforms, вы можете использовать этот подход stackoverflow.com/a/33675039/1818723
Павел Чиох
Гэри Вудфайн подробно описал это в очень хорошем стиле в своем
Javad Norouzi
@javad Только частично; Я оказался здесь, потому что мне нужна была часть DI, которую он обещал, но я не нашел. Он также не показал, как использовать несколько файлов конфигурации, как в этом примере.
Auspex
234

Для консольного приложения .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

луч
источник
1
Как я заметил, Microsoft не использует IConfigurationRoot в своих примерах, а использует IConfiguration.
aligin
3
IConfigurationRootвсе еще доступен в .NET Core 2.0 . Он наследуется от, IConfigurationно считается производным от него, что обычно не используется . Тем не менее, пример кода был обновлен, чтобы не включать его и избежать путаницы.
Ray
10
2 примечания: в пункте 4 вам нужен только Microsoft.Extensions.Configuration.Json ... Он будет включать остальные 2 по умолчанию. Во-вторых: если вы хотите загрузить раздел в объект, полезно знать: var options = new FooOptions (); ConfigurationBinder.Bind (configuration.GetSection ("foo"), параметры); Вам понадобится Microsoft.Extensions.Options.ConfigurationExtensions
Yepeekai
1
открытый класс FooOptions {общедоступная строка myKey1 {получить; set;} публичная строка myKey2 {get; set;}}
Yepeekai
2
Инструменты> Диспетчер пакетов NuGet> Консоль диспетчера пакетов .. .. Установить-пакет Microsoft.Extensions.Configuration .. Установить-пакет Microsoft.Extensions.Configuration.FileExtensions .. Установить-пакет Microsoft.Extensions.Configuration.Json
Manohar Reddy Poreddy
19

Если вы используете Microsoft.Extensions.Hosting(версия 2.1.0+) для размещения консоли приложения и asp.net ядро приложения, все ваши конфигурации инъецируют HostBuilder«s ConfigureAppConfigurationи ConfigureHostConfigurationметодов. Вот демонстрация того, как добавить 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настраивается неправильно
Sinaesthetic
Вы должны использовать среду в качестве ключа, проверьте этот код: github.com/aspnet/Hosting/blob/dev/src/…
Feiyu Zhou
@FeiyuZhou, это мертвая ссылка
Auspex
Разве все это решение не new HostBuilder()избыточно? Не HostBuilderделает все это внутренне?
Auspex
@Auspex Это зависит от того, как вы определяете консольное приложение. Если вам нужно определить собственные конфигурации, вы должны сделать это так. Вот документ для ядра dotnet 3.0: docs.microsoft.com/en-us/aspnet/core/fundamentals/host/…
Feiyu Zhou
10

Я ошибался. Вы можете использовать новый ConfigurationBuilderиз консольного приложения netcore.

См. Пример на https://docs.asp.net/en/latest/fundamentals/configuration.html .

Однако только ядро ​​aspnet имеет встроенную функцию внедрения зависимостей, поэтому у вас нет возможности иметь строго типизированные параметры конфигурации и автоматически вводить их с использованием IOptions.

kimsagro
источник
9
Этот ответ действителен, но он должен содержать необходимый код, поэтому голосов за него не будет.
Матиас
4
Все, что вам нужно, это добавить пакет: Microsoft.Extensions.Optionsи позвонитьservice.AddOptions();
Бруно Гарсия
2
Кажется, что вся (очень длинная) связанная страница связана с ASP.NET, с упоминанием "WebHost" в каждом примере. Я пришел к этому SO-вопросу после того, как нашел связанную страницу и подумал: «Хорошо, это ASP.NET, а как насчет консольных приложений».
mackenir
Это немного странно, @mackenir, потому что в 3.0 все было реорганизовано, и теперь это просто Host! Единственная ссылка на сам WebHost - это ссылка на документацию 2.2. Они могли бы немного пояснить, что ConfigureWebHostDefaults()вызовы в примерах необязательны и только для веб-приложений.
Auspex
4

Для основного консольного приложения 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();

Вы можете ввести ILoggerFactory, IConfiguration в SomeService.

lnaie
источник
3

В .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"
        }
      }
    ]
  }
Эрнест
источник
После того, как я попробовал весь этот синтаксис со всего Интернета, у меня сработал именно ваш, и он такой простой.
GaneshT
Я рад, что это помогло тебе.
Эрнест
1

Для этого можно использовать библиотеку LiteWare.Configuration . Он очень похож на оригинал .NET Framework ConfigurationManagerи работает с .NET Core / Standard. С точки зрения кода вы получите что-то вроде:

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

Отказ от ответственности: я являюсь автором LiteWare.Configuration.

Хишам Маударбокус
источник
0

Просто накапливаю ... похоже на пост Фэйю Чжоу. Здесь я добавляю имя машины.

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>();
  }
bvj
источник
0

Установите эти пакеты:

  • 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, если они новее: содержание

alansiqueira27
источник