ENPT

Adicionando um arquivo de configuração JSON a uma aplicação de console .NET Core

Uma aplicação .NET Core pode lidar com configuração usando diferentes formatos (providers) como memória, linha de comando e variáveis de ambiente. Aqui, usaremos um provider de arquivo, mais especificamente um JsonConfigurationProvider. Clique neste link para saber mais sobre os diferentes tipos de providers de configuração.

Configuração do projeto

Vamos começar criando uma aplicação de console e adicionando o pacote NuGet do provider. No nosso caso, será um provider JSON.

dotnet new console -o sample-configuration -n SampleConfiguration
cd SampleConfiguration
dotnet add package Microsoft.Extensions.Configuration.Json

Vamos também adicionar um arquivo appsettings.json que podemos usar para testes.

{
  "ConnectionStrings": {
    "Sample": "Server=(localdb)\\mssqllocaldb;Database=Sample;Trusted_Connection=True;"
  },
  "TheSettings": {
    "IsEnabled": true,
    "Delay": "00:01:00"
  }
}

Não é obrigatório, mas você pode querer adicionar CopyToOutputDirectory no arquivo do seu projeto.

<Project Sdk="Microsoft.NET.Sdk">

	...

  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>

Configuração

Podemos agora adicionar algum código para a nossa aplicação de exemplo.

using System;
using System.IO;
using Microsoft.Extensions.Configuration;

namespace SampleConfiguration
{
    class Program
    {
        static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetParent(AppContext.BaseDirectory).FullName)
                .AddJsonFile("appsettings.json", optional: false)
                .Build();
        }
    }
}

O método Build() retorna uma nova instância de ConfigurationRoot. Já podemos usar isso para recuperar informações do nosso arquivo de configuração. Por exemplo, poderíamos obter a connection string usando apenas a sua chave.

var connectionString = configuration.GetConnectionString("Sample");
Console.WriteLine(connectionString);

Poderíamos fazer o mesmo para acessar outras configurações, mas existe uma forma melhor. Vamos criar uma classe que mapeará nossa seção de configuração.

class MySettings
{
    public bool IsEnabled { get; set; }
    public TimeSpan Delay { get; set; }
}

Para conseguir fazer isso, precisamos adicionar outro pacote NuGet.

> dotnet add package Microsoft.Extensions.Configuration.Binder

Esse pacote fornece um método de extensão .Bind() que pode mapear uma seção do nosso arquivo de configuração para uma instância de uma classe. No nosso caso, queremos ler toda a configuração dentro de TheSettings para uma instância de MySettings.

var mySettings = new MySettings();
configuration.GetSection("TheSettings").Bind(mySettings);
Console.WriteLine("IsEnabled: " + mySettings.IsEnabled);
Console.WriteLine("Delay: " + mySettings.Delay);

Conclusão

O processo para configurar um arquivo de configuração não é evidente com o .NET Core, e também mudou bastante desde o primeiro lançamento. Mas é muito mais flexível e leve do que a solução fornecida com o .NET Framework completo.

Veja como fica o nosso código-fonte final.

using System;
using System.IO;
using Microsoft.Extensions.Configuration;

namespace SampleConfiguration
{
    class Program
    {
        static void Main()
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetParent(AppContext.BaseDirectory).FullName)
                .AddJsonFile("appsettings.json", optional: false)
                .Build();

            var connectionString = configuration.GetConnectionString("Sample");
            Console.WriteLine(connectionString);

            var mySettings = new MySettings();
            configuration.GetSection("TheSettings").Bind(mySettings);
            Console.WriteLine("IsEnabled: " + mySettings.IsEnabled);
            Console.WriteLine("Delay: " + mySettings.Delay);
        }
    }

		class MySettings
		{
		    public bool IsEnabled { get; set; }
		    public TimeSpan Delay { get; set; }
		}
}