Proveedores de configuración en .NET

La configuración en .NET se realiza con proveedores de configuración. Hay varios tipos de proveedores que dependen de varios orígenes de configuración. En este artículo se detallan los distintos proveedores de configuración y sus orígenes correspondientes.

Proveedor de configuración de archivo

FileConfigurationProvider es la clase base para cargar la configuración del sistema de archivos. Los siguientes proveedores de configuración se derivan de FileConfigurationProvider:

Las claves no distinguen mayúsculas de minúsculas. Todos los proveedores de configuración de archivos inician el FormatException cuando se encuentran claves duplicadas en un único proveedor.

Proveedor de configuración JSON

La clase JsonConfigurationProvider carga la configuración desde un archivo JSON. Instale el paquete NuGet Microsoft.Extensions.Configuration.Json.

Las sobrecargas pueden especificar:

  • Si el archivo es opcional.
  • Si la configuración se recarga si el archivo cambia.

Observe el código siguiente:

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

El código anterior:

  • Borra todos los proveedores de configuración existentes que se agregaron de forma predeterminada en el método CreateApplicationBuilder(String[]).
  • Configura el proveedor de configuración de JSON para cargar los archivos appsettings.json y appsettings.Environment.json con las opciones siguientes:
    • optional: true: el archivo es opcional.
    • reloadOnChange: true: el archivo se recarga cuando se guardan los cambios.

Importante

Al agregar proveedores de configuración con IConfigurationBuilder.Add, el proveedor de configuración agregado se agrega al final de la lista IConfigurationSource. Cuando varios proveedores encuentran claves, el último proveedor en leer la clave reemplaza a los proveedores anteriores.

A continuación se muestra un ejemplo de archivo appsettings.json con varios valores de configuración:

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

Desde la instancia de IConfigurationBuilder, una vez agregados los proveedores de configuración, puede llamar a IConfigurationBuilder.Build() para obtener el objeto IConfigurationRoot. La raíz de configuración representa la raíz de una jerarquía de configuración. Las secciones de la configuración se pueden enlazar a instancias de objetos .NET y, posteriormente, se pueden proporcionar como IOptions<TOptions> mediante la inserción de dependencias.

Nota

Las propiedades Acción de compilación y Copiar en el directorio de salida del archivo JSON deben establecerse en Contenido y Copiar si es posterior (o Copiar siempre), respectivamente.

Observe la clase TransientFaultHandlingOptions definida como se indica a continuación:

namespace ConsoleJson.Example;

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

El código siguiente compila la raíz de la configuración, enlaza una sección al tipo de clase TransientFaultHandlingOptions e imprime los valores enlazados en la ventana de la consola:

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

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

La aplicación escribe la salida de ejemplo siguiente:

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

Proveedor de configuración XML

La clase XmlConfigurationProvider carga la configuración desde un archivo XML en tiempo de ejecución. Instale el paquete NuGet Microsoft.Extensions.Configuration.Xml.

En el código siguiente se muestra la configuración de archivos XML mediante el proveedor de configuración 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();

El código anterior:

  • Borra todos los proveedores de configuración existentes que se agregaron de forma predeterminada en el método CreateApplicationBuilder(String[]).
  • Configura el proveedor de configuración XML para cargar los archivos appsettings.xml y repeating-example.xml con las siguientes opciones:
    • optional: true: el archivo es opcional.
    • reloadOnChange: true: el archivo se recarga cuando se guardan los cambios.
  • Configura el proveedor de configuración de variables de entorno.
  • Configura el proveedor de configuración de línea de comandos si el valor args especificado contiene argumentos.

La configuración XML se reemplaza por la configuración del proveedor de configuración de variables de entorno y del proveedor de configuración de línea de comandos.

A continuación se muestra un ejemplo de archivo appsettings.xml con varios valores de configuración:

<?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>

Sugerencia

Para usar el IConfiguration tipo en aplicaciones winForms, agregue una referencia al paquete NuGet Microsoft.Extensions.Configuration.Xml. Cree una instancia de ConfigurationBuilder y llamadas de cadena a AddXmlFile y Build(). Para más información, consulte .NET Docs Issue #29679.

En .NET 5 y versiones anteriores, agregue el atributo name para distinguir los elementos repetitivos que usan el mismo nombre de elemento. En .NET 6 y versiones posteriores, el proveedor de configuración XML indexa automáticamente los elementos repetitivos. Eso significa que no tiene que especificar el atributo name, salvo si quiere el índice "0" en la clave y solo hay un elemento. (Si va a actualizar a .NET 6 o una versión posterior, es posible que encuentre una interrupción como resultado de este cambio en el comportamiento. Para obtener más información, vea Los elementos XML repetidos incluyen el í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>

El código siguiente lee el archivo de configuración anterior y muestra las claves y los 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}");

La aplicación escribiría la siguiente salida de ejemplo:

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

Los atributos se pueden usar para suministrar valores:

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

El archivo de configuración anterior carga las siguientes claves con value:

  • key:attribute
  • section:key:attribute

Proveedor de configuración INI

La clase IniConfigurationProvider carga la configuración desde un archivo INI en tiempo de ejecución. Instale el paquete NuGet Microsoft.Extensions.Configuration.Ini.

En el código siguiente se borran todos los proveedores de configuración y se agregan los IniConfigurationProvider con dos archivos INI como origen:

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

A continuación se muestra un ejemplo de archivo appsettings.ini con varios valores de configuración:

SecretKey="Secret key value"

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

[Logging:LogLevel]
Default=Information
Microsoft=Warning

En el código siguiente se muestran los valores de configuración anteriores escribiéndolo en la ventana de la consola:

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

La aplicación escribiría la siguiente salida de ejemplo:

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

Proveedor de configuración de variables de entorno

Al usar la configuración predeterminada, EnvironmentVariablesConfigurationProvider carga la configuración de los pares clave-valor de la variable de entorno después de leer appsettings.json, appsettings.Environment.json y el Administrador de secretos. Por lo tanto, los valores de clave que se leen del entorno reemplazan los valores que se leen de appsettings.json, appsettings.Environment.json y del administrador de secretos.

El delimitador : no funciona con claves jerárquicas de variables de entorno en todas las plataformas. Por ejemplo, el delimitador : no es compatible con Bash. El doble carácter de subrayado (__), que se admite en todas las plataformas, reemplaza automáticamente cualquier delimitador : en variables de entorno.

Considere la clase TransientFaultHandlingOptions:

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

Los comandos set siguientes establecen las claves de entorno y los valores de SecretKey y TransientFaultHandlingOptions.

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

Esta configuración de entorno solo se establece en los procesos iniciados desde la ventana de comandos en la que se han establecido. No los leen las aplicaciones web que se inician con Visual Studio.

Con Visual Studio 2019 y versiones posteriores, puede especificar variables de entorno mediante el cuadro de diálogo Launch Profiles (Iniciar perfiles).

Launch Profiles dialog showing environment variables

Los siguientes comandos setx se pueden usar para establecer las claves de entorno y los valores en Windows. A diferencia de set, la configuración de setx se conserva. /M establece la variable en el entorno del sistema. Si no se usa el modificador /M, se establece una variable de entorno de usuario.

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

Para comprobar que los comandos anteriores invalidan cualquier configuración de appsettings.json y appsettings.Environment.json, haga lo siguiente:

  • Con Visual Studio: salga y reinicie Visual Studio.
  • Con la CLI: abra una nueva ventana de comandos y escriba dotnet run.

Prefijos

Llame a AddEnvironmentVariables con una cadena a fin de especificar un prefijo para las variables de entorno:

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

En el código anterior:

  • config.AddEnvironmentVariables(prefix: "CustomPrefix_") se agrega después de los proveedores de configuración predeterminados. Para obtener un ejemplo de ordenación de los proveedores de configuración, consulte Proveedor de configuración XML.
  • Las variables de entorno establecidas con el prefijo CustomPrefix_ invalidan los proveedores de configuración predeterminados. Esto incluye las variables de entorno sin el prefijo.

El prefijo se quita cuando se leen los pares clave-valor de configuración.

La configuración predeterminada carga las variables de entorno y los argumentos de la línea de comandos con el prefijo DOTNET_. .NET usa el prefijo DOTNET_ para la configuración del host y la configuración de la aplicación, pero no para la del usuario.

Para obtener más información sobre la configuración del host y de la aplicación, consulte el artículo Host genérico de .NET.

Prefijos de cadena de conexión

La API de configuración tiene reglas de procesamiento especiales para cuatro variables de entorno de cadena de conexión. Estas cadenas de conexión están implicadas en la configuración de las cadenas de conexión de Azure para el entorno de la aplicación. Las variables de entorno con los prefijos que se muestran en la tabla se cargan en la aplicación con la configuración predeterminada o cuando no se proporciona ningún prefijo a AddEnvironmentVariables.

Prefijo de cadena de conexión Proveedor
CUSTOMCONNSTR_ Proveedor personalizado
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

Cuando una variable de entorno se detecta y carga en la configuración con cualquiera de los cuatro prefijos que se muestran en la tabla:

  • La clave de configuración se crea al quitar el prefijo de la variable de entorno y al agregar una sección de clave de configuración (ConnectionStrings).
  • Se crea un nuevo par clave-valor de configuración que representa el proveedor de conexión de base de datos (excepto para CUSTOMCONNSTR_, que no tiene ningún proveedor indicado).
Clave de variable de entorno Clave de configuración convertida Entrada de configuración del proveedor
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} Entrada de configuración no creada.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} Clave: ConnectionStrings:{KEY}_ProviderName:
Valor: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} Clave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} Clave: ConnectionStrings:{KEY}_ProviderName:
Valor: System.Data.SqlClient

Variables de entorno configuradas en launchSettings.json

Las variables de entorno configuradas en launchSettings.json invalidan aquellas configuradas en el entorno del sistema.

Configuración de Azure App Service

En Azure App Service, seleccione Nueva configuración de la aplicación en la página Configuración>Configuración. Los ajustes de configuración de Azure App Service:

  • Se cifran en reposo y se transmiten a través de un canal cifrado.
  • Se exponen como variables de entorno.

Proveedor de configuración de línea de comandos

Si se usa la configuración predeterminada, CommandLineConfigurationProvider carga la configuración de los pares de clave-valor de argumento de la línea de comandos después de los siguientes orígenes de configuración:

  • Archivos appsettings.json y appsettings.Environment.json.
  • Secretos de aplicación (administrador de secretos) en el entorno Development.
  • Variables de entorno.

De forma predeterminada, los valores de configuración establecidos en la línea de comandos reemplazan los valores de configuración establecidos con el resto de proveedores de configuración.

Con Visual Studio 2019 y versiones posteriores, puede especificar argumentos de la línea de comandos mediante el cuadro de diálogo Launch Profiles (Iniciar perfiles).

Launch Profiles dialog showing command-line arguments

Argumentos de la línea de comandos

El comando siguiente establece las claves y los valores mediante =:

dotnet run SecretKey="Secret key from command line"

El comando siguiente establece las claves y los valores mediante /:

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

El comando siguiente establece las claves y los valores mediante --:

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

El valor de la clave:

  • Debe seguir a un signo =, o bien la clave debe tener un prefijo -- o / cuando el valor sigue a un espacio.
  • No es necesario si se usa =. Por ejemplo: SomeKey=.

Dentro del mismo comando, no mezcle pares clave-valor de argumento de la línea de comandos que usan = con pares de clave-valor que usan un espacio.

Proveedor de configuración de clave por archivo

KeyPerFileConfigurationProvider usa los archivos de un directorio como pares clave-valor de configuración. La clave es el nombre de archivo. El valor es el contenido del archivo. El proveedor de configuración de clave por archivo se usa en escenarios de hospedaje de Docker.

Para activar la configuración de clave por archivo, llame al método de extensión AddKeyPerFile en una instancia de ConfigurationBuilder. La ruta de acceso directoryPath a los archivos debe ser una ruta de acceso absoluta.

Las sobrecargas permiten especificar:

  • Un delegado Action<KeyPerFileConfigurationSource> que configura el origen.
  • Si el directorio es opcional y la ruta de acceso al directorio.

El carácter de subrayado doble (__) se usa como delimitador de claves de configuración en los nombres de archivo. Por ejemplo, el nombre de archivo Logging__LogLevel__System genera la clave de configuración Logging:LogLevel:System.

Llame a ConfigureAppConfiguration cuando cree el host para especificar la configuración de la aplicación:

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

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

Proveedor de configuración de memoria

MemoryConfigurationProvider usa una colección en memoria como pares clave-valor de configuración.

El código siguiente agrega una colección en memoria al sistema de configuración:

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

En el código anterior, MemoryConfigurationBuilderExtensions.AddInMemoryCollection(IConfigurationBuilder, IEnumerable<KeyValuePair<String,String>>) agrega el proveedor de memoria después de los proveedores de configuración predeterminados. Para obtener un ejemplo de ordenación de los proveedores de configuración, consulte Proveedor de configuración XML.

Vea también