Konfiguracja ASP.NET Core dla aplikacji konsoli .NET Core

Odpowiedzi:

77

Możesz użyć tego fragmentu kodu. Obejmuje konfigurację i 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>();

        ............
    }
}

Aha, i nie zapomnij dodać pliku 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
źródło
12
Ta odpowiedź nie jest idealna. Użyj Directory.GetCurrentDirectory()zamiast AppContext.BaseDirectory. Później nie powinno być potrzeby hakowania.
Matyas
1
Lub ustaw właściwość „Kopiuj do katalogu wyjściowego” na „Kopiuj, jeśli nowszy” w programie Visual Studio dla plików JSON.
BuddhiP
Aby katalog bazowy działał w sieci Web, konsoli i Winforms, możesz użyć tego podejścia stackoverflow.com/a/33675039/1818723
Paweł Cioch
Gary Woodfine opisał to szczegółowo w bardzo dobrym stylu w tym poście: garywoodfine.com/configuration-api-net-core-console-application
Javad
1
Wygląda na to SetBasePath, że nie ma metody, chyba że ją dodasz Microsoft.Extensions.Configuration.FileExtensions. I nie AddJsonFilebezMicrosoft.Extensions.Configuration.Json
Douglas Gaskell
246

W przypadku aplikacji konsoli .NET Core 2.0 wykonałem następujące czynności:

  1. Utwórz nowy plik o nazwie appsettings.json w katalogu głównym projektu (nazwa pliku może być dowolna)
  2. Dodaj moje ustawienia do tego pliku jako json. Na przykład:
{
  "myKey1" :  "my test value 1", 
  "myKey2" :  "my test value 2", 
  "foo" :  "bar" 
}
  1. Skonfiguruj kopiowanie pliku do katalogu wyjściowego za każdym razem, gdy projekt jest budowany (w VS -> Eksplorator rozwiązań -> kliknij plik prawym przyciskiem myszy -> wybierz „Właściwości” -> Zaawansowane -> Kopiuj do katalogu wyjściowego -> wybierz „Kopiuj zawsze”)

  2. Zainstaluj następujący pakiet NuGet w moim projekcie:

    • Microsoft.Extensions.Configuration.Json
  3. Dodaj następujące elementy do Program.cs (lub gdziekolwiek Main()się znajduje):

    static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");
    
        var configuration = builder.Build();
    
        // rest of code...
    }
    
  4. Następnie przeczytaj wartości, korzystając z jednego z następujących sposobów:

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

Więcej informacji: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration?tabs=basicconfiguration#simple-configuration

Promień
źródło
1
Jak zauważyłem, Microsoft nie używa IConfigurationRoot w swoich przykładach, ale używa IConfiguration.
aligin
3
IConfigurationRootjest nadal dostępny w .NET Core 2.0 . Dziedziczy po, IConfigurationale jest uważany za przypadek pochodny, który nie jest powszechnie używany . Niezależnie od tego przykładowy kod został zaktualizowany, aby go nie uwzględniać i uniknąć nieporozumień.
Ray
10
2 uwagi: w punkcie 4 potrzebujesz tylko Microsoft.Extensions.Configuration.Json ... Domyślnie będzie zawierać pozostałe 2. Po drugie: jeśli chcesz załadować sekcję do obiektu, warto wiedzieć: var options = new FooOptions (); ConfigurationBinder.Bind (configuration.GetSection ("foo"), opcje); Będziesz potrzebował Microsoft.Extensions.Options.ConfigurationExtensions
Yepeekai
1
public class FooOptions {public string myKey1 {get; set;} public string myKey2 {get; set;}}
Yepeekai
2
Narzędzia> Menedżer pakietów NuGet> Konsola Menedżera pakietów .. .. Zainstaluj pakiet Microsoft.Extensions.Configuration .. Zainstaluj pakiet Microsoft.Extensions.Configuration.FileExtensions .. Zainstaluj pakiet Microsoft.Extensions.Configuration.Json
Manohar Reddy Poreddy
21

Jeśli używasz Microsoft.Extensions.Hosting(wersja 2.1.0+), aby udostępnić swoje app konsoli i ASP.NET podstawową aplikację, wszystkie konfiguracje są wstrzykiwane z HostBuilder„s ConfigureAppConfigurationi ConfigureHostConfigurationmetod. Oto demo o tym, jak dodać appsettings.jsonzmienne środowiskowe i:

    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
        //;

Aby skompilować powyższy kod, musisz dodać następujące pakiety:

<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" />
Feiyu Zhou
źródło
Jak określa się środowisko? Jeśli utworzę profil w launchSettings, to faktycznie ustawia się, ASPNETCORE_ENVIRONMENTale potem context.HostingEnvironment.EnvironmentNamenie jest ustawiany poprawnie
Sinaesthetic
Powinieneś użyć środowiska jako klucza, sprawdź ten kod: github.com/aspnet/Hosting/blob/dev/src/ ...
Feiyu Zhou
@FeiyuZhou to martwy link
Auspex
Czy całe to rozwiązanie nie jest new HostBuilder()zbędne? Czy nie HostBuilderrobi tego wszystkiego wewnętrznie?
Auspex
1
@Auspex To zależy od tego, jak zdefiniujesz aplikację konsoli. Jeśli potrzebujesz zdefiniować niestandardowe konfiguracje, powinieneś ustawić w ten sposób. Oto dokumentacja dotnet core 3.0: docs.microsoft.com/en-us/aspnet/core/fundamentals/host/ ...
Feiyu Zhou
10

Myliłem się. Możesz użyć nowego ConfigurationBuilderz aplikacji konsoli netcore.

Przykład można znaleźć pod adresem https://docs.asp.net/en/latest/fundamentals/configuration.html .

Jednak tylko rdzeń aspnet ma iniekcję zależności po wyjęciu z pudełka, więc nie możesz mieć silnie wpisanych ustawień konfiguracji i automatycznie wstrzykiwać je przy użyciu IOptions.

kimsagro
źródło
9
Ta odpowiedź jest prawidłowa, ale powinna zawierać niezbędny kod, więc nie ma za nią głosu.
Matyas
4
Wystarczy dodać paczkę: Microsoft.Extensions.Optionsi zadzwonićservice.AddOptions();
Bruno Garcia
2
Cała (bardzo długa) połączona strona wydaje się być związana z ASP.NET, ze wzmianką o „WebHost” w każdym przykładzie. Dotarłem do tego pytania SO po znalezieniu połączonej strony i pomyślałem "ok, to ASP.NET, a co z aplikacjami konsolowymi".
mackenir
To trochę dziwne, @mackenir, ponieważ w wersji 3.0 wszystko zostało refaktoryzowane, tak że to tylko Host! Jedynym odniesieniem do samego WebHost jest wskazanie dokumentacji 2.2. Mogliby być trochę jaśniejsi, że ConfigureWebHostDefaults()wywołania w przykładach są opcjonalne i tylko dla aplikacji internetowych.
Auspex
6

Na .Net Core 3.1 wystarczy zrobić to:

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

Korzystanie z SeriLog będzie wyglądać następująco:

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();
            }
        }
    }
}

Sekcja appsetings.json programu Serilog do generowania jednego pliku dziennie będzie wyglądać następująco:

  "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"
        }
      }
    ]
  }
Ernest
źródło
po wypróbowaniu wszystkich tych składni z całej sieci, twoja jest tą, która zadziałała dla mnie i jest taka prosta.
GaneshT,
Cieszę się, że ci pomogło.
Ernest
4

To jest mniej więcej tak, dla podstawowej aplikacji konsoli 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();

Możesz wstrzyknąć ILoggerFactory, IConfiguration w SomeService.

lnaie
źródło
2

Jeśli używasz .netcore 3.1 najprostszym sposobem jest użycie nowego systemu konfiguracyjnego do wywołania CreateDefaultBuildermetody klasy statycznej Hosti skonfigurowania aplikacji

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;
    }
}

Musisz ustawić Copy to Output Directory = 'Copy if newer' dla plików, appsettings.jsona appsettings.{environment}.json także możesz ustawić zmienną środowiskową {prefix} ENVIRONMENT (domyślny prefiks to DOTNET ), aby umożliwić wybór określonych parametrów konfiguracyjnych.

Plik .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>
Dmitry Kolchev
źródło
Och, wreszcie dziękuję za wskazanie mi właściwego kierunku! Rozróżnienie ASP.NET.CORE i DOTNET.CORE jest bardzo ważne. W przypadku korzystania z aplikacji .NET Core (nie aplikacji internetowych asp, ale konsoli lub usług Windows / Linux dla mikrousług), należy ustawić zmienne środowiskowe debugowania na DOTNET_ENVIRONMENT . Wtedy będzie działać z context.HostingEnviornment.EnviornmentName.
rogaa
1

Możesz użyć do tego biblioteki LiteWare.Configuration . Jest bardzo podobny do oryginalnego .NET Framework ConfigurationManageri działa na platformie .NET Core / Standard. Jeśli chodzi o kod, otrzymasz coś takiego:

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

Zastrzeżenie: Jestem autorem LiteWare.Configuration.

Hisham Maudarbocus
źródło
0

Po prostu piętrzą się ... podobnie jak post Feiyu Zhou. Tutaj dodaję nazwę maszyny.

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
źródło
0

Zainstaluj te pakiety:

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

Kod:

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();
    }

Klasa MySettingsConfig:

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

Twoje ustawienia aplikacji mogą być tak proste, jak to: wprowadź opis obrazu tutaj

Ponadto ustaw pliki appsettings na Content / Copy if nower: zadowolony

alansiqueira27
źródło