Provedores de configuração no .NET

É possível fazer a configuração no .NET com provedores de configuração. Há vários tipos de provedores que dependem de várias fontes de configuração. Este artigo detalha todos os diferentes provedores de configuração e as origens correspondentes.

Provedor de configuração de arquivo

FileConfigurationProvider é a classe base para carregamento da configuração do sistema de arquivos. Os seguintes provedores de configuração derivam de FileConfigurationProvider:

As chaves não diferenciam maiúsculas de minúsculas. Todos os provedores de configuração de arquivo geram a FormatException quando chaves duplicadas são encontradas em um só provedor.

Provedor de configuração JSON

A classe JsonConfigurationProvider carrega a configuração de um arquivo JSON. Instale o pacote do NuGet Microsoft.Extensions.Configuration.Json.

As sobrecargas podem especificar:

  • Se o arquivo é opcional.
  • Se a configuração será recarregada caso o arquivo seja alterado.

Considere o seguinte código:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using ConsoleJson.Example;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.Sources.Clear();

IHostEnvironment env = builder.Environment;

builder.Configuration
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);

TransientFaultHandlingOptions options = new();
builder.Configuration.GetSection(nameof(TransientFaultHandlingOptions))
    .Bind(options);

Console.WriteLine($"TransientFaultHandlingOptions.Enabled={options.Enabled}");
Console.WriteLine($"TransientFaultHandlingOptions.AutoRetryDelay={options.AutoRetryDelay}");

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

O código anterior:

  • Limpa todos os provedores de configuração existentes que foram adicionados por padrão no método CreateApplicationBuilder(String[]).
  • Configura o provedor de configuração JSON para carregar os arquivos appsettings.json e appsettings.Environment.json com as seguintes opções:
    • optional: true: o arquivo é opcional.
    • reloadOnChange: true: o arquivo é recarregado quando as alterações são salvas.

Importante

Ao adicionar provedores de configuração com IConfigurationBuilder.Add, o provedor de configuração é adicionado ao final da lista IConfigurationSource. Quando as chaves são encontradas por vários provedores, o último provedor a ler a chave substitui os provedores anteriores.

Veja um arquivo appsettings.json de exemplo com várias configurações:

{
    "SecretKey": "Secret key value",
    "TransientFaultHandlingOptions": {
        "Enabled": true,
        "AutoRetryDelay": "00:00:07"
    },
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    }
}

Na instância IConfigurationBuilder, depois que os provedores de configuração são adicionados, você pode chamar IConfigurationBuilder.Build() para obter o objeto IConfigurationRoot. A raiz de configuração representa a raiz de uma hierarquia de configuração. As seções da configuração podem ser associadas a instâncias de objetos .NET e depois fornecidas como IOptions<TOptions> por meio de injeção de dependência.

Observação

As propriedades Build Action e Copy to Output Directory do arquivo JSON precisam ser definidas como Content e Copy if newer (or Copy always), respectivamente.

Considere a classe TransientFaultHandlingOptions definida da seguinte maneira:

namespace ConsoleJson.Example;

public sealed class TransientFaultHandlingOptions
{
    public bool Enabled { get; set; }
    public TimeSpan AutoRetryDelay { get; set; }
}

Este código cria a raiz de configuração, associa uma seção ao tipo de classe TransientFaultHandlingOptions e imprime os valores associados na janela do console:

TransientFaultHandlingOptions options = new();
builder.Configuration.GetSection(nameof(TransientFaultHandlingOptions))
    .Bind(options);

Console.WriteLine($"TransientFaultHandlingOptions.Enabled={options.Enabled}");
Console.WriteLine($"TransientFaultHandlingOptions.AutoRetryDelay={options.AutoRetryDelay}");

O aplicativo grava a seguinte saída de exemplo:

// Sample output:
//    TransientFaultHandlingOptions.Enabled=True
//    TransientFaultHandlingOptions.AutoRetryDelay=00:00:07

Provedor de configuração XML

A classe XmlConfigurationProvider carrega a configuração de um arquivo XML em tempo de execução. Instale o pacote do NuGet Microsoft.Extensions.Configuration.Xml.

O código a seguir demonstra a configuração de arquivos XML usando o provedor de configuração XML.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.Sources.Clear();

builder.Configuration
    .AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true)
    .AddXmlFile("repeating-example.xml", optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();

if (args is { Length: > 0 })
{
    builder.Configuration.AddCommandLine(args);
}

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

O código anterior:

  • Limpa todos os provedores de configuração existentes que foram adicionados por padrão no método CreateApplicationBuilder(String[]).
  • Configura o provedor de configuração XML para carregar os arquivos appsettings.xml e repeating-example.xml com as seguintes opções:
    • optional: true: o arquivo é opcional.
    • reloadOnChange: true: o arquivo é recarregado quando as alterações são salvas.
  • Configura o provedor de configuração de variáveis de ambiente.
  • Configure o provedor de configuração de linha de comando se o args fornecido contiver argumentos.

As configurações do XML são substituídas pelas configurações no Provedor de configuração de variáveis de ambiente e no Provedor de configuração de linha de comando.

Veja um arquivo appsettings.xml de exemplo com várias definições de configuração:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <SecretKey>Secret key value</SecretKey>
  <TransientFaultHandlingOptions>
    <Enabled>true</Enabled>
    <AutoRetryDelay>00:00:07</AutoRetryDelay>
  </TransientFaultHandlingOptions>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

Dica

Para usar o tipo IConfiguration em aplicativos WinForms, adicione uma referência ao pacote NuGet Microsoft.Extensions.Configuration.Xml. Instancie o ConfigurationBuilder e encadeie as chamadas para AddXmlFile e Build(). Saiba mais em .NET Docs Issue #29679.

No .NET 5 e em versões anteriores, adicione o atributo name para distinguir elementos repetidos que usam o mesmo nome de elemento. No .NET 6 e nas versões posteriores, o provedor de configuração XML indexa automaticamente elementos repetidos. Isso significa que você não precisa especificar o atributo name, exceto se quiser o índice "0" na chave e houver apenas um elemento. (Se você estiver atualizando para o .NET 6 ou posterior, poderá sofrer uma interrupção resultante dessa alteração no comportamento. Para obter mais informações, confira Elementos XML repetidos incluem índice.)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

O código a seguir lê o arquivo de configuração anterior e exibe as chaves e os valores:

IConfigurationRoot configurationRoot = builder.Configuration;

string key00 = "section:section0:key:key0";
string key01 = "section:section0:key:key1";
string key10 = "section:section1:key:key0";
string key11 = "section:section1:key:key1";

string? val00 = configurationRoot[key00];
string? val01 = configurationRoot[key01];
string? val10 = configurationRoot[key10];
string? val11 = configurationRoot[key11];

Console.WriteLine($"{key00} = {val00}");
Console.WriteLine($"{key01} = {val01}");
Console.WriteLine($"{key10} = {val10}");
Console.WriteLine($"{key10} = {val11}");

O aplicativo gravaria a seguinte saída de exemplo:

// Sample output:
//    section:section0:key:key0 = value 00
//    section:section0:key:key1 = value 01
//    section:section1:key:key0 = value 10
//    section:section1:key:key0 = value 11

É possível usar atributos para fornecer valores:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

O arquivo de configuração anterior carrega as seguintes chaves com value:

  • key:attribute
  • section:key:attribute

Provedor de configuração INI

A classe IniConfigurationProvider carrega a configuração de um arquivo INI em tempo de execução. Instale o pacote do NuGet Microsoft.Extensions.Configuration.Ini.

Este código limpa todos os provedores de configuração e adiciona IniConfigurationProvider com dois arquivos INI como a origem:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Configuration.Sources.Clear();

IHostEnvironment env = builder.Environment;

builder.Configuration
    .AddIniFile("appsettings.ini", optional: true, reloadOnChange: true)
    .AddIniFile($"appsettings.{env.EnvironmentName}.ini", true, true);

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

Veja um arquivo appsettings.json de exemplo com várias definições de configuração:

SecretKey="Secret key value"

[TransientFaultHandlingOptions]
Enabled=True
AutoRetryDelay="00:00:07"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

Este código exibe as definições de configuração anteriores escrevendo-as na janela do console:

foreach ((string key, string? value) in
    builder.Configuration.AsEnumerable().Where(t => t.Value is not null))
{
    Console.WriteLine($"{key}={value}");
}

O aplicativo gravaria a seguinte saída de exemplo:

// Sample output:
//    TransientFaultHandlingOptions:Enabled=True
//    TransientFaultHandlingOptions:AutoRetryDelay=00:00:07
//    SecretKey=Secret key value
//    Logging:LogLevel:Microsoft=Warning
//    Logging:LogLevel:Default=Information

Provedor de configuração de variáveis de ambiente

Usando a configuração padrão, EnvironmentVariablesConfigurationProvider carrega a configuração de pares chave-valor de variáveis de ambiente depois de ler appsettings.json, appsettings.Environment.json e o gerente de segredos. Portanto, os valores de chave lidos do ambiente substituem os valores lidos de appsettings.json, appsettings.Environment.json e do gerente de segredos.

O delimitador : não funciona com chaves hierárquicas de variáveis de ambiente em todas as plataformas. Por exemplo, o delimitador : não é compatível com Bash. O sublinhado duplo (__), que tem suporte em todas as plataformas, substitui automaticamente qualquer delimitador : em variáveis de ambiente.

Considere a classe TransientFaultHandlingOptions:

public class TransientFaultHandlingOptions
{
    public bool Enabled { get; set; }
    public TimeSpan AutoRetryDelay { get; set; }
}

Os comandos set a seguir definem as chaves de ambiente e os valores de SecretKey e TransientFaultHandlingOptions.

set SecretKey="Secret key from environment"
set TransientFaultHandlingOptions__Enabled="true"
set TransientFaultHandlingOptions__AutoRetryDelay="00:00:13"

Essas configurações de ambiente são definidas apenas em processos iniciados na janela de comando em que foram definidas. Elas não serão lidas por aplicativos Web iniciados com o Visual Studio.

Com o Visual Studio 2019 e posteriores, você pode especificar variáveis de ambiente usando o diálogo Perfis de Inicialização.

Launch Profiles dialog showing environment variables

Os comandos setx a seguir podem ser usados para definir as chaves de ambiente e os valores no Windows. Diferente de set, as configurações setx são persistentes. /M define a variável no ambiente do sistema. Se o comutador /M não for usado, uma variável de ambiente do usuário será definida.

setx SecretKey "Secret key from setx environment" /M
setx TransientFaultHandlingOptions__Enabled "true" /M
setx TransientFaultHandlingOptions__AutoRetryDelay "00:00:05" /M

Para testar se os comandos anteriores substituem alguma configuração appsettings.json e appsettings.Environment.json:

  • Com o Visual Studio: saia e reinicie o Visual Studio.
  • Com a CLI: inicie uma nova janela de comando e insira dotnet run.

Prefixos

Para especificar um prefixo para variáveis de ambiente, chame AddEnvironmentVariables com uma cadeia de caracteres:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.AddEnvironmentVariables(prefix: "CustomPrefix_");

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

No código anterior:

  • config.AddEnvironmentVariables(prefix: "CustomPrefix_") é adicionado após os provedores de configuração padrão. Para obter um exemplo de ordenação dos provedores de configuração, confira Provedor de configuração XML.
  • As variáveis de ambiente definidas com o prefixo CustomPrefix_ substituem os provedores de configuração padrão. Isso inclui variáveis de ambiente sem o prefixo.

O prefixo é removido quando os pares de valores-chave de configuração são lidos.

A configuração padrão carrega variáveis de ambiente e argumentos de linha de comando prefixados com DOTNET_. O prefixo DOTNET_ é usado pelo .NET para configuração de host e de aplicativo, mas não para configuração de usuário.

Para obter mais informações sobre configuração de host e aplicativo, confira Host genérico do .NET.

Prefixos de cadeia de conexão

A API de configuração tem regras de processamento especiais para quatro variáveis de ambiente de cadeia de conexão. Essas cadeias de conexão estão envolvidas na configuração de cadeias de conexão do Azure para o ambiente do aplicativo. As variáveis de ambiente com os prefixos mostrados na tabela são carregadas no aplicativo com a configuração padrão ou quando nenhum prefixo é fornecido ao AddEnvironmentVariables.

Prefixo da cadeia de conexão Provedor
CUSTOMCONNSTR_ Provedor personalizado
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Banco de Dados SQL do Azure
SQLCONNSTR_ SQL Server

Quando uma variável de ambiente for descoberta e carregada na configuração com qualquer um dos quatro prefixos mostrados na tabela:

  • A chave de configuração é criada removendo o prefixo da variável de ambiente e adicionando uma seção de chave de configuração (ConnectionStrings).
  • Um novo par chave-valor de configuração é criado para representar o provedor de conexão de banco de dados (exceto para CUSTOMCONNSTR_, que não tem um provedor indicado).
Chave de variável de ambiente Chave de configuração convertida Entrada de configuração do provedor
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} Entrada de configuração não criada.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} Chave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient

Variáveis de ambiente definidas no launchSettings.json

As variáveis de ambiente definidas no launchSettings.json substituem as definidas no ambiente do sistema.

Configurações do Serviço de Aplicativo do Azure

Em Serviço de Aplicativo do Azure, selecione Nova configuração de aplicativo na página Definições>Configurações. As configurações do aplicativo do Serviço de Aplicativo do Azure são:

  • Criptografadas em repouso e transmitidas por um canal criptografado.
  • Expostas como variáveis de ambiente.

Provedor de configuração de linha de comando

Usando a configuração padrão, o CommandLineConfigurationProvider carrega a configuração dos pares chave-valor do argumento da linha de comando após as seguintes fontes de configuração:

  • Arquivos appsettings.json e appsettings.Environment.json.
  • Segredos do aplicativo (Gerenciador de Segredos) no ambiente Development.
  • Variáveis de ambiente.

Por padrão, os valores de configuração definidos na linha de comando substituem os valores de configuração definidos com todos os outros provedores de configuração.

Com o Visual Studio 2019 e posteriores, você pode especificar argumentos de linha de comando usando o diálogo Perfis de Inicialização.

Launch Profiles dialog showing command-line arguments

Argumentos de linha de comando

O comando a seguir define chaves e valores usando =:

dotnet run SecretKey="Secret key from command line"

O comando a seguir define chaves e valores usando /:

dotnet run /SecretKey "Secret key set from forward slash"

O comando a seguir define chaves e valores usando --:

dotnet run --SecretKey "Secret key set from double hyphen"

O valor da chave:

  • Deve seguir =, ou a chave deve ter um prefixo de -- ou / quando o valor vier após um espaço.
  • Não é necessário se = for usado. Por exemplo, SomeKey=.

No mesmo comando, não combine pares chave-valor do argumento de linha de comando que usam um sinal de =l com pares chave-valor que usam um espaço.

Provedor de configuração de chave por arquivo

O KeyPerFileConfigurationProvider usa arquivos do diretório como pares chave-valor de configuração. A chave é o nome do arquivo. O valor é o conteúdo do arquivo. O provedor de configuração de chave por arquivo é usado em cenários de hospedagem do Docker.

Para ativar a configuração de chave por arquivo, chame o método de extensão AddKeyPerFile em uma instância do ConfigurationBuilder. O directoryPath para os arquivos deve ser um caminho absoluto.

As sobrecargas permitem especificar:

  • Um delegado Action<KeyPerFileConfigurationSource> que configura a origem.
  • Se o diretório é opcional, e o caminho para o diretório.

O sublinhado duplo (__) é usado como um delimitador de chave de configuração em nomes de arquivo. Por exemplo, o nome do arquivo Logging__LogLevel__System produz a chave de configuração Logging:LogLevel:System.

Chame ConfigureAppConfiguration ao criar o host para especificar a configuração do aplicativo:

.ConfigureAppConfiguration((_, configuration) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");

    configuration.AddKeyPerFile(directoryPath: path, optional: true);
})

Provedor de configuração de memória

O MemoryConfigurationProvider usa uma coleção na memória como pares chave-valor de configuração.

O código a seguir adiciona uma coleção de memória ao sistema de configuração:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.AddInMemoryCollection(
    new Dictionary<string, string?>
    {
        ["SecretKey"] = "Dictionary MyKey Value",
        ["TransientFaultHandlingOptions:Enabled"] = bool.TrueString,
        ["TransientFaultHandlingOptions:AutoRetryDelay"] = "00:00:07",
        ["Logging:LogLevel:Default"] = "Warning"
    });

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

No código anterior, MemoryConfigurationBuilderExtensions.AddInMemoryCollection(IConfigurationBuilder, IEnumerable<KeyValuePair<String,String>>) adiciona o provedor de memória após os provedores de configuração padrão. Para obter um exemplo de ordenação dos provedores de configuração, confira Provedor de configuração XML.

Confira também