Configuração do ASP.NET Core para aplicativo de console do .NET Core

Respostas:

76

Você pode usar esse trecho de código. Inclui configuração e 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>();

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

Ah, e não se esqueça de adicionar o 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
fonte
12
Esta resposta não é ideal. Use em Directory.GetCurrentDirectory()vez de AppContext.BaseDirectory. Não deve haver necessidade de hackear depois.
Matyas
1
Ou defina a propriedade "Copiar no diretório de saída" como "Copiar se mais recente" no Visual Studio para os arquivos JSON.
BuddhiP 15/05
Para dir base para o trabalho em Web, Console e WinForms você pode usar essa abordagem stackoverflow.com/a/33675039/1818723
Pawel Cioch
Gary Woodfine descreveu isso em detalhes em um estilo muito bom sobre este post: garywoodfine.com/configuration-api-net-core-console-application
Javad Norouzi
@javad Apenas parcialmente; Eu acabei aqui porque queria a parte do DI, que ele prometeu, mas eu não encontrei. Ele também não mostrou como usar vários arquivos de configuração como este exemplo.
Auspex #
232

Para um aplicativo de console do .NET Core 2.0, fiz o seguinte:

  1. Crie um novo arquivo chamado appsettings.json na raiz do projeto (o nome do arquivo pode ser qualquer coisa)
  2. Adicione minhas configurações específicas a esse arquivo como json. Por exemplo:
{
  "myKey1" :  "my test value 1", 
  "myKey2" :  "my test value 2", 
  "foo" :  "bar" 
}
  1. Configure para copiar o arquivo no diretório de saída sempre que o projeto for criado (em VS -> Solution Explorer -> arquivo com o botão direito do mouse -> selecione 'Propriedades' -> Avançado -> Copiar para Diretório de Saída -> selecione 'Copiar Sempre')

  2. Instale o seguinte pacote de nuget no meu projeto:

    • Microsoft.Extensions.Configuration.Json
  3. Adicione o seguinte ao Program.cs (ou onde quer que Main()esteja):

    static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");
    
        var configuration = builder.Build();
    
        // rest of code...
    }
  4. Em seguida, leia os valores usando uma das seguintes maneiras:

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

Mais informações: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration?tabs=basicconfiguration#simple-configuration

Raio
fonte
1
Como notei, a Microsoft não usa IConfigurationRoot em seus exemplos, mas usa IConfiguration.
aligin
3
IConfigurationRootainda está disponível no .NET Core 2.0 . Ele é herdado, IConfigurationmas é considerado um caso derivado, que não é comumente usado . Independentemente disso, o exemplo de código foi atualizado para não incluí-lo e evitar qualquer confusão.
Raio
10
2 notas: no ponto 4, você só precisa do Microsoft.Extensions.Configuration.Json ... Ele incluirá os outros 2 por padrão. Segundo: se você deseja carregar uma seção em um objeto, é útil saber: var options = new FooOptions (); ConfigurationBinder.Bind (configuration.GetSection ("foo"), opções); Você vai precisar de Microsoft.Extensions.Options.ConfigurationExtensions
Yepeekai
1
classe pública FooOptions {public string myKey1 {get; set;} public string myKey2 {get; set;}}
Yepeekai 13/03/18
2
Ferramentas> Gerenciador de Pacotes NuGet> Console do Gerenciador de Pacotes .. .. Pacote de Instalação Microsoft.Extensions.Configuration .. Pacote de Instalação Microsoft.Extensions.Configuration.FileExtensions .. Pacote de Instalação Microsoft.Extensions.Configuration.Json
Manohar Reddy Poreddy
19

Se você usar Microsoft.Extensions.Hosting(versão 2.1.0+) para hospedar seu aplicativo de console e o aplicativo principal do asp.net, todas as suas configurações serão injetadas com HostBuilder's ConfigureAppConfiguratione ConfigureHostConfigurationmétodos. Aqui está a demonstração sobre como adicionar as appsettings.jsonvariáveis ​​de ambiente e:

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

Para compilar o código acima, você precisa adicionar estes pacotes:

<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
fonte
Como é determinado o ambiente? Se eu criar um perfil no launchSettings, ele realmente sets ASPNETCORE_ENVIRONMENT, mas depois context.HostingEnvironment.EnvironmentNamenão está sendo definido corretamente
Sinaesthetic
Você deve usar o ambiente como chave, verifique este código: github.com/aspnet/Hosting/blob/dev/src/…
Feiyu Zhou
@FeiyuZhou que é um elo morto
Auspex
Toda essa solução não é new HostBuilder()redundante? Não HostBuilderfaz tudo internamente?
Auspex
@Auspex Depende de como você define seu aplicativo de console. Se você precisar definir configurações personalizadas, deverá definir assim. Aqui está o documento para o dotnet core 3.0: docs.microsoft.com/en-us/aspnet/core/fundamentals/host/…
Feiyu Zhou
10

Eu estava errado. Você pode usar o novo ConfigurationBuilderem um aplicativo de console netcore.

Veja https://docs.asp.net/en/latest/fundamentals/configuration.html para um exemplo.

No entanto, apenas o núcleo do aspnet tem injeção de dependência pronta para uso, para que você não tenha a capacidade de definir fortemente as configurações digitadas e injetá-las automaticamente usando IOptions.

kimsagro
fonte
9
Esta resposta é válida, mas deve conter o código necessário, portanto, não há votos positivos.
Matyas
4
Tudo que você precisa é adicionar o pacote: Microsoft.Extensions.Optionse chamadaservice.AddOptions();
Bruno Garcia
2
A página vinculada (muito longa) inteira parece estar relacionada ao ASP.NET, com menção a "WebHost" em todos os exemplos. Cheguei a essa questão de SO depois de encontrar a página vinculada e pensar "ok, isso é ASP.NET, e os aplicativos de console".
Mackenir #
Isso é um pouco estranho, @mackenir, porque no 3.0 tudo foi refatorado para que tudo seja apenas Host! A única referência ao próprio WebHost é apontar para a documentação 2.2. Eles poderiam ter sido um pouco mais claros de que as ConfigureWebHostDefaults()chamadas nos exemplos são opcionais e apenas para aplicativos da Web.
Auspex
4

É algo assim, para um aplicativo de console central 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();

Você pode injetar ILoggerFactory, IConfiguration no SomeService.

lnaie
fonte
2

No .Net Core 3.1, precisamos apenas fazer o seguinte:

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

O uso do SeriLog será semelhante a:

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

E a seção Serilog appsetings.json para gerar um arquivo diariamente terá a seguinte aparência:

  "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
fonte
depois de experimentar todas essas sintaxes de toda a web, é a sua que funcionou para mim e é muito simples.
GaneshT 04/07
Estou feliz que isso te ajudou.
Ernest
1

Você pode usar a biblioteca LiteWare.Configuration para isso. É muito semelhante ao original do .NET Framework ConfigurationManagere funciona para o .NET Core / Standard. Em termos de código, você terminará com algo como:

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

Disclaimer: Eu sou o autor do LiteWare.Configuration.

Hisham Maudarbocus
fonte
0

Apenas empilhando ... semelhante ao post de Feiyu Zhou. Aqui estou adicionando o nome da máquina.

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
fonte
0

Instale estes pacotes:

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

Código:

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

Classe MySettingsConfig:

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

Suas configurações de aplicativos podem ser tão simples quanto isto: insira a descrição da imagem aqui

Além disso, defina os arquivos de configurações de aplicativos como Conteúdo / Copiar, se mais recente: conteúdo

alansiqueira27
fonte