Konfiguration in .NET
Die Konfiguration in .NET erfolgt mithilfe eines oder mehrerer Konfigurationsanbieter. Konfigurationsanbieter lesen Konfigurationsdaten unter Verwendung verschiedener Konfigurationsquellen aus Schlüssel-Wert-Paaren:
- Einstellungsdateien, z. B. appsettings.json
- Umgebungsvariablen
- Azure Key Vault
- Azure App Configuration
- Befehlszeilenargumente
- Benutzerdefinierte Anbieter (installiert oder erstellt)
- Verzeichnisdateien
- Speicherinterne .NET Objekte
- Drittanbieter
Hinweis
Informationen zum Konfigurieren der .NET Runtime selbst finden Sie unter Konfigurationseinstellungen für .NET Runtime.
Konzepte und Abstraktionen
Bei einer oder mehreren Konfigurationsquellen stellt der Typ IConfiguration eine einheitliche Ansicht der Konfigurationsdaten bereit. Die Konfiguration ist schreibgeschützt, und das Konfigurationsmuster kann nicht programmgesteuert geschrieben werden. Die Schnittstelle IConfiguration
ist eine einzelne Repräsentation aller Konfigurationsquellen, wie im folgenden Diagramm dargestellt:
Konfigurieren von Konsolen-Apps
.NET-Konsolenanwendungen, die mit der Befehlsvorlage dotnet new oder mit Visual Studio erstellt werden, machen standardmäßig keine Konfigurationsfunktionen verfügbar. Um Konfigurationsmöglichkeiten in einer neuen .NET-Konsolenanwendung hinzuzufügen, müssen Sie Microsoft.Extensions.Configuration einen Paketverweis hinzufügen. Dieses Paket ist die Grundlage für die Konfiguration in .NET-Apps. Sie stellt den ConfigurationBuilder und verwandte Typen bereit.
using Microsoft.Extensions.Configuration;
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>()
{
["SomeKey"] = "SomeValue"
})
.Build();
Console.WriteLine(configuration["SomeKey"]);
// Outputs:
// SomeValue
Der vorangehende Code:
- Erstellt eine neue ConfigurationBuilder-Instanz.
- Fügt dem Konfigurations-Generator eine Speicherauflistung von Schlüssel-Wert-Paaren hinzu.
- Ruft die Build()-Methode auf, um eine IConfiguration-Instanz zu erstellen.
- Gibt den Wert des Schlüssels
SomeKey
an der Konsole aus.
In diesem Beispiel wird zwar eine Konfiguration im Arbeitsspeicher verwendet, es gibt jedoch zahlreiche Konfigurationsanbieter, die Funktionen für dateibasierte Konfigurationsquellen, Umgebungsvariablen, Befehlszeilenargumente u. v. m. verfügbar machen. Weitere Informationen finden Sie unter Konfigurationsanbieter in .NET.
Alternativer Hostingansatz
Häufig erledigen Ihre Apps mehr als nur die Lesekonfiguration. Sie werden wahrscheinlich Abhängigkeitsinjektionen, Protokollierung und andere Dienste verwenden. Für Apps, die diese Dienste verwenden, wird der Ansatz mit generischem .NET-Host empfohlen. Erwägen Sie stattdessen das Hinzufügen eines Paketverweises in Microsoft.Extensions.Hosting. Ändern Sie die Program.cs-Datei so, dass Sie dem folgenden Code entspricht:
using Microsoft.Extensions.Hosting;
using IHost host = Host.CreateApplicationBuilder(args).Build();
// Application code should start here.
await host.RunAsync();
Die Methode Host.CreateApplicationBuilder(String[]) legt die Standardkonfiguration für die App in der folgenden Reihenfolge fest, von der höchsten zur niedrigsten Priorität:
- Befehlszeilenargumente, die den Befehlszeilen-Konfigurationsanbieter verwenden
- Umgebungsvariablen, die den Umgebungsvariablen-Konfigurationsanbieter verwenden
- App-Geheimnisse, wenn die App in der
Development
-Umgebung ausgeführt wird - appsettings.json mithilfe des JSON-Konfigurationsanbieters.
- appsettings.
Environment
.json mithilfe des JSON-Konfigurationsanbieters. Beispiel: „appsettings.Production.json“ und „appsettings.Development.json“. - ChainedConfigurationProvider: Fügt eine vorhandene
IConfiguration
als Quelle hinzu.
Durch Hinzufügen eines Konfigurationsanbieters werden vorherige Konfigurationswerte überschrieben. Beispielsweise überschreibt der Befehlszeilen-Konfigurationsanbieter alle Werte von anderen Anbietern, da er zuletzt hinzugefügt wurde. Wenn SomeKey
sowohl in appsettings.json als auch in der Umgebung festgelegt ist, wird der Umgebungswert verwendet, da dieser nach appsettings.json hinzugefügt wurde.
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:
- IConfiguration: Stellt Schlüssel-Wert-Anwendungskonfigurationseigenschaften dar.
- IConfigurationRoot: Stellt den Stamm einer
IConfiguration
-Hierarchie dar. - IConfigurationSection: Stellt einen Abschnitt von Anwendungskonfigurationswerten dar.
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 Konfigurationswerte auf unterschiedliche Weise verarbeiten:
- Direkte Deserialisierung (mithilfe integrierter Konverter) für primitive Typen.
- Mit dem TypeConverter für einen komplexen Typ, sofern der Typ über einen solchen verfügt.
- Reflexion für einen komplexen Typ mit Eigenschaften.
Hinweis
Für den Binder gelten einige Einschränkungen:
- Eigenschaften werden ignoriert, wenn sie private Setter haben oder ihr Typ nicht konvertiert werden kann.
- Eigenschaften ohne entsprechende Konfigurationsschlüssel werden ignoriert.
Bindungshierarchien
Konfigurationswerte können hierarchische Daten enthalten. Hierarchische Objekte werden unter Verwendung des Trennzeichens :
in den Konfigurationsschlüsseln dargestellt. Um auf einen Konfigurationswert zuzugreifen, verwenden Sie das Zeichen :
zum Trennen von Hierarchiewerten. Sehen Sie sich beispielsweise die folgenden Konfigurationswerte an:
{
"Parent": {
"FavoriteNumber": 7,
"Child": {
"Name": "Example",
"GrandChild": {
"Age": 3
}
}
}
}
Die folgende Tabelle stellt Beispielschlüssel und die entsprechenden Werte für die vorangehende Beispiel-JSON dar:
Schlüssel | Wert |
---|---|
"Parent:FavoriteNumber" |
7 |
"Parent:Child:Name" |
"Example" |
"Parent:Child:GrandChild:Age" |
3 |
Einfaches Beispiel
Um auf Konfigurationswerte in ihrer Grundform zuzugreifen – ohne Unterstützung des Ansatzes mit einem generischen Host –, verwenden Sie den Typ ConfigurationBuilder direkt.
Tipp
Der Typ System.Configuration.ConfigurationBuilder unterscheidet sich vom Typ Microsoft.Extensions.Configuration.ConfigurationBuilder. 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>net8.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="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
</ItemGroup>
</Project>
Die Projektdatei oben verweist auf mehrere NuGet-Konfigurationspakete:
- Microsoft.Extensions.Configuration.Binder: Funktionalität zum Binden eines Objekts an Daten in Konfigurationsanbietern für
Microsoft.Extensions.Configuration
. - Microsoft.Extensions.Configuration.Json: Implementierung des JSON-Konfigurationsanbieters für
Microsoft.Extensions.Configuration
. - Microsoft.Extensions.Configuration.EnvironmentVariables: Implementierung des Umgebungsvariablen-Konfigurationsanbieters für
Microsoft.Extensions.Configuration
.
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"
]
}
}
Hier finden Sie ein Beispiel für ein Nutzungsmuster, das den Konfigurations-Generator anhand dieser JSON-Datei direkt verwendet:
using Microsoft.Extensions.Configuration;
// Build a config object, using env vars and JSON providers.
IConfigurationRoot 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 entsprechendeSettings
-Instanz mithilfe derconfig
-Instanz ab.
Das Settings
-Objekt ist wie folgt geformt:
public sealed class Settings
{
public required int KeyOne { get; set; }
public required bool KeyTwo { get; set; }
public required NestedSettings KeyThree { get; set; } = null!;
}
public sealed class NestedSettings
{
public required 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>net8.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="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>
</Project>
Die obige 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.CreateApplicationBuilder(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.CreateApplicationBuilder
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
Sehen Sie sich die Inhalte der appsettings.json-Datei aus dem vorherigen Beispiel an:
{
"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.CreateApplicationBuilder(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, wobei sowohl jeder Schlüssel als auch der Wert eine Zeichenfolge ist. 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 ein und derselbe Schlüssel von mehr als einem Anbieter bereitgestellt wird, wird der zuletzt hinzugefügte Anbieter verwendet.
Weitere Informationen zu verschiedenen Konfigurationsanbietern finden Sie unter Konfigurationsanbieter in .NET.
Siehe auch
- Konfigurationsanbieter in .NET
- Implementieren eines benutzerdefinierten Konfigurationsanbieters
- Konfigurationsfehler sollten im Repository github.com/dotnet/runtime/ erstellt werden.
- Konfiguration in ASP.NET Core