Konfiguration in .NET

Die Konfiguration in .NET erfolgt mithilfe eines oder mehrerer Konfigurationsanbieter. Konfigurationsanbieter lesen Konfigurationsdaten aus Schlüssel-Wert-Paaren unter Verwendung verschiedener Konfigurationsquellen:

  • Einstellungsdateien, z. B. appsettings.json
  • Umgebungsvariablen
  • Azure Key Vault
  • Azure App Configuration
  • Befehlszeilenargumente
  • Benutzerdefinierte Anbieter (installiert oder erstellt)
  • Verzeichnisdateien
  • Speicherinterne .NET Objekte
  • Drittanbieter

Konzepte und Abstraktionen

Angesichts einer oder mehrerer Konfigurationsquellen stellt der IConfiguration Typ eine einheitliche Ansicht der Konfigurationsdaten bereit. Die Konfiguration ist schreibgeschützt, und das Konfigurationsmuster ist nicht programmgesteuert beschreibbar. Die IConfiguration Schnittstelle ist eine einzelne Darstellung aller Konfigurationsquellen, wie im folgenden Diagramm dargestellt:

The `IConfiguration` interface is a single representation of all the configuration sources.

Konfigurieren von Konsolen-Apps

.NET-Konsolenanwendungen, die mithilfe der dotnet neuen Befehlsvorlage erstellt wurden oder Visual Studio standardmäßig keine Konfigurationsfunktionen verfügbar machen. Fügen Sie zum Hinzufügen der Konfiguration in einer neuen .NET-Konsolenanwendung einen Paketverweis zu Microsoft.Extensions.Hosting hinzu. Ändern Sie die Program.cs-Datei so, dass Sie dem folgenden Code entspricht:

using Microsoft.Extensions.Hosting;

using IHost host = Host.CreateDefaultBuilder(args).Build();

// Application code should start here.

await host.RunAsync();

Die Host.CreateDefaultBuilder(String[])-Methode legt die Standardkonfiguration für die App in der folgenden Reihenfolge fest:

  1. ChainedConfigurationProvider: Fügt eine vorhandene IConfiguration als Quelle hinzu.
  2. appsettings.json mithilfe des JSON-Konfigurationsanbieters.
  3. appsettings.Environment.json mithilfe des JSON-Konfigurationsanbieters. Beispiel: „appsettings.Production.json“ und „appsettings.Development.json“.
  4. App-Geheimnisse, wenn die App in der -Umgebung ausgeführt wird
  5. Umgebungsvariablen, die den Umgebungsvariablen-Konfigurationsanbieter verwenden
  6. Befehlszeilenargumente, die den Befehlszeilen-Konfigurationsanbieter verwenden

Später hinzugefügte Konfigurationsanbieter überschreiben vorherige Schlüsseleinstellungen. Wenn beispielsweise SomeKey sowohl unter appsettings.json als auch unter Umgebung festgelegt wird, wird der Umgebungswert verwendet. Bei Verwendung der Standardkonfigurationsanbieter überschreibt der Befehlszeilen-Konfigurationsanbieter alle anderen Anbieter.

Bindung

Einer der Hauptvorteile der Verwendung der .NET-Konfigurationsabstraktionen ist die Möglichkeit, Konfigurationswerte an Instanzen von .NET-Objekten zu binden. JSON-Konfigurationsanbieter können zum Beispiel verwendet werden, um appsettings.json-Dateien .NET-Objekten zuzuordnen, und sie werden mit Abhängigkeitsinjektion verwendet. Damit wird das Optionsmuster aktiviert. Dieses verwendet Klassen, um stark typisierten Zugriff auf zusammengehörige Einstellungsgruppen zu ermöglichen. Die .NET-Konfiguration bietet verschiedene Abstraktionen. Betrachten Sie die folgenden Schnittstellen:

Diese Abstraktionen sind unabhängig von ihrem zugrunde liegenden Konfigurationsanbieter (IConfigurationProvider). Anders ausgedrückt: Sie können eine IConfiguration-Instanz verwenden, um auf jeden Konfigurationswert von mehreren Anbietern zuzugreifen.

Der Binder kann verschiedene Ansätze zum Verarbeiten von Konfigurationswerten verwenden:

  • Direkte Deserialisierung (mit integrierten Konvertern) für Grundtypen.
  • Die TypeConverter für einen komplexen Typ, wenn der Typ eine hat.
  • Spiegelung für einen komplexen Typ mit Eigenschaften.

Hinweis

Der Binder verfügt über einige Einschränkungen:

  • Eigenschaften werden ignoriert, wenn sie private Setter haben oder deren Typ nicht konvertiert werden kann.
  • Eigenschaften ohne entsprechende Konfigurationsschlüssel werden ignoriert.

Bindungshierarchien

Konfigurationswerte können hierarchische Daten enthalten. Hierarchische Objekte werden mit der Verwendung des : Trennzeichens in den Konfigurationsschlüsseln dargestellt. Um auf einen Konfigurationswert zuzugreifen, verwenden Sie das : Zeichen, um eine Hierarchie zu trennen. Berücksichtigen Sie beispielsweise die folgenden Konfigurationswerte:

{
  "Parent": {
    "FavoriteNumber": 7,
    "Child": {
      "Name": "Example",
      "GrandChild": {
        "Age": 3
      }
    }
  }
}

In der folgenden Tabelle werden Beispielschlüssel und deren entsprechende Werte für das vorherige Beispiel JSON dargestellt:

Schlüssel Wert
"Parent:FavoriteNumber" 7
"Parent:Child:Name" "Example"
"Parent:Child:GrandChild:Age" 3

Einfaches Beispiel

Um auf Konfigurationswerte in ihrem grundlegenden Formular zuzugreifen, ohne die Unterstützung des generischen Hostansatzes , verwenden Sie den ConfigurationBuilder Typ direkt.

Tipp

Der System.Configuration.ConfigurationBuilder Typ unterscheidet sich vom Microsoft.Extensions.Configuration.ConfigurationBuilder Typ. Alle diese Inhalte sind spezifisch für die Microsoft.Extensions.*-NuGet-Pakete und -Namespaces.

Sehen Sie sich folgenden C#-Projekt an:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="appsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.0" />
  </ItemGroup>

</Project>

Die Projektdatei oben verweist auf mehrere NuGet-Konfigurationspakete:

Sehen Sie sich eine Datei appsettings.json an:

{
    "Settings": {
        "KeyOne": 1,
        "KeyTwo": true,
        "KeyThree": {
            "Message": "Oh, that's nice...",
            "SupportedVersions": {
                "v1": "1.0.0",
                "v3": "3.0.7"
            }
        },
        "IPAddressRange": [
            "46.36.198.121",
            "46.36.198.122",
            "46.36.198.123",
            "46.36.198.124",
            "46.36.198.125"
        ]
    }
}

Anhand dieser JSON-Datei wird hier ein Beispiel für ein Verbrauchsmuster gezeigt, das den Konfigurations-Generator direkt verwendet:

using Microsoft.Extensions.Configuration;

// Build a config object, using env vars and JSON providers.
IConfiguration config = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .AddEnvironmentVariables()
    .Build();

// Get values from the config given their key and their target type.
Settings settings = config.GetRequiredSection("Settings").Get<Settings>();

// Write the values to the console.
Console.WriteLine($"KeyOne = {settings.KeyOne}");
Console.WriteLine($"KeyTwo = {settings.KeyTwo}");
Console.WriteLine($"KeyThree:Message = {settings.KeyThree.Message}");

// Application code which might rely on the config could start here.

// This will output the following:
//   KeyOne = 1
//   KeyTwo = True
//   KeyThree:Message = Oh, that's nice...

Für den C#-Code oben gilt:

  • Er instanziiert ConfigurationBuilder.
  • Er fügt die "appsettings.json"-Datei hinzu, die vom JSON-Konfigurationsanbieter erkannt werden soll.
  • Er fügt Umgebungsvariablen hinzu, die vom Umgebungsvariablen-Konfigurationsanbieter erkannt werden sollen.
  • Ruft den erforderlichen "Settings" Abschnitt und die entsprechende Settings Instanz mithilfe der config Instanz ab.

Das Settings-Objekt ist wie folgt geformt:

public sealed class Settings
{
    public int KeyOne { get; set; }
    public bool KeyTwo { get; set; }
    public NestedSettings KeyThree { get; set; } = null!;
}
public sealed class NestedSettings
{
    public string Message { get; set; } = null!;
}

Einfaches Beispiel mit Hosting

Um auf den IConfiguration-Wert zu zugreifen, können Sie erneut das NuGet-Paket Microsoft.Extensions.Hosting verwenden. Erstellen Sie eine neue Konsolenanwendung, und fügen Sie die folgenden Projektdateiinhalte ein:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="appsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
  </ItemGroup>

</Project>

Die vorstehende Projektdatei definiert Folgendes:

  • Die Anwendung ist eine ausführbare Datei.
  • Eine appsettings.json-Datei soll beim Kompilieren des Projekts in das Ausgabeverzeichnis kopiert werden.
  • Der NuGet-Paketverweis Microsoft.Extensions.Hosting wird hinzugefügt.

Fügen Sie die appsettings.json-Datei im Stammverzeichnis des Projekts mit folgendem Inhalt hinzu:

{
    "KeyOne": 1,
    "KeyTwo": true,
    "KeyThree": {
        "Message": "Thanks for checking this out!"
    }
}

Ersetzen Sie den Inhalt der Datei Program.cs durch den folgenden C#-Code:

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

using IHost host = Host.CreateDefaultBuilder(args).Build();

// Ask the service provider for the configuration abstraction.
IConfiguration config = host.Services.GetRequiredService<IConfiguration>();

// Get values from the config given their key and their target type.
int keyOneValue = config.GetValue<int>("KeyOne");
bool keyTwoValue = config.GetValue<bool>("KeyTwo");
string keyThreeNestedValue = config.GetValue<string>("KeyThree:Message");

// Write the values to the console.
Console.WriteLine($"KeyOne = {keyOneValue}");
Console.WriteLine($"KeyTwo = {keyTwoValue}");
Console.WriteLine($"KeyThree:Message = {keyThreeNestedValue}");

// Application code which might rely on the config could start here.

await host.RunAsync();

// This will output the following:
//   KeyOne = 1
//   KeyTwo = True
//   KeyThree:Message = Thanks for checking this out!

Wenn Sie diese Anwendung ausführen, definiert Host.CreateDefaultBuilder das Verhalten, um die JSON-Konfiguration zu erkennen und über die IConfiguration-Instanz verfügbar zu machen. Aus der host-Instanz können Sie die IConfiguration-Instanz vom Dienstanbieter abrufen und dann Werte abrufen.

Tipp

Die Verwendung der rohen IConfiguration-Instanz auf diese Weise ist zwar praktisch, aber nicht sehr gut skalierbar. Wenn Anwendungen und damit die entsprechenden Konfigurationen komplexer werden, empfehlen wir, das Optionsmuster als Alternative zu verwenden.

Grundlegendes Beispiel für das Hosten und Verwenden der Indexer-API

Betrachten Sie denselben Dateiinhalt von appsettings.json aus dem vorherigen Beispiel:

{
    "SupportedVersions": {
        "v1": "1.0.0",
        "v3": "3.0.7"
    },
    "IPAddressRange": [
        "46.36.198.123",
        "46.36.198.124",
        "46.36.198.125"
    ]
}

Ersetzen Sie den Inhalt der Datei Program.cs durch den folgenden C#-Code:

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

using IHost host = Host.CreateDefaultBuilder(args).Build();

// Ask the service provider for the configuration abstraction.
IConfiguration config = host.Services.GetRequiredService<IConfiguration>();

// Get values from the config given their key and their target type.
string ipOne = config["IPAddressRange:0"];
string ipTwo = config["IPAddressRange:1"];
string ipThree = config["IPAddressRange:2"];
string versionOne = config["SupportedVersions:v1"];
string versionThree = config["SupportedVersions:v3"];

// Write the values to the console.
Console.WriteLine($"IPAddressRange:0 = {ipOne}");
Console.WriteLine($"IPAddressRange:1 = {ipTwo}");
Console.WriteLine($"IPAddressRange:2 = {ipThree}");
Console.WriteLine($"SupportedVersions:v1 = {versionOne}");
Console.WriteLine($"SupportedVersions:v3 = {versionThree}");

// Application code which might rely on the config could start here.

await host.RunAsync();

// This will output the following:
//     IPAddressRange:0 = 46.36.198.123
//     IPAddressRange:1 = 46.36.198.124
//     IPAddressRange:2 = 46.36.198.125
//     SupportedVersions:v1 = 1.0.0
//     SupportedVersions:v3 = 3.0.7

Auf die Werte wird mithilfe der Indexer-API zugegriffen, bei der jeder Schlüssel eine Zeichenfolge ist, und der Wert ist eine Zeichenfolge. Die Konfiguration unterstützt Eigenschaften, Objekte, Arrays und Wörterbücher.

Konfigurationsanbieter

Die folgende Tabelle zeigt die für .NET Core-Apps verfügbaren Konfigurationsanbieter.

Anbieter Bereitstellung der Konfiguration über
Azure-App-Konfigurationsanbieter Azure App Configuration
Azure Key Vault-Konfigurationsanbieter Azure Key Vault
Befehlszeilen-Konfigurationsanbieter Befehlszeilenparameter
Benutzerdefinierter Konfigurationsanbieter Benutzerdefinierte Quelle
Umgebungsvariablen-Konfigurationsanbieter Umgebungsvariablen
Dateikonfigurationsanbieter JSON-, XML-und INI-Dateien
Schlüssel-pro-Datei-Konfigurationsanbieter Verzeichnisdateien
Speicherkonfigurationsanbieter In-Memory-Sammlungen
App-Geheimnisse (Secret Manager) Datei im Benutzerprofilverzeichnis

Tipp

Die Reihenfolge, in der Konfigurationsanbieter hinzugefügt werden, ist wichtig. Wenn mehrere Konfigurationsanbieter verwendet werden und mehr als ein bereitgestellter Schlüssel denselben Schlüssel angibt, wird der letzte hinzugefügte Verwendet.

Weitere Informationen zu verschiedenen Konfigurationsanbietern finden Sie unter Konfigurationsanbieter in .NET.

Siehe auch