Configuratie in .NET

Configuratie in .NET wordt uitgevoerd met behulp van een of meer configuratieproviders. Configuratieproviders lezen configuratiegegevens van sleutel-waardeparen met behulp van verschillende configuratiebronnen:

  • Instellingen bestanden, zoals appsettings.json
  • Omgevingsvariabelen
  • Azure Key Vault
  • Azure App Configuration
  • Opdrachtregelargumenten
  • Aangepaste providers, geïnstalleerd of gemaakt
  • Mapbestanden
  • .NET-objecten in het geheugen
  • Externe providers

Notitie

Zie .NET Runtime-configuratie-instellingen voor informatie over het configureren van de .NET Runtime-runtime zelf.

Concepten en abstracties

Gezien een of meer configuratiebronnen biedt het IConfiguration type een uniforme weergave van de configuratiegegevens. De configuratie is alleen-lezen en het configuratiepatroon is niet ontworpen om programmatisch schrijfbaar te zijn. De IConfiguration interface is één weergave van alle configuratiebronnen, zoals wordt weergegeven in het volgende diagram:

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

Console-apps configureren

.NET-consoletoepassingen die zijn gemaakt met behulp van de nieuwe dotnet-opdrachtsjabloon of Visual Studio maken standaard geen configuratiemogelijkheden beschikbaar. Als u configuratie wilt toevoegen in een nieuwe .NET-consoletoepassing, voegt u een pakketverwijzing toe aan Microsoft.Extensions.Configuration. Dit pakket vormt de basis voor configuratie in .NET-apps. Het biedt de ConfigurationBuilder en gerelateerde typen.

using Microsoft.Extensions.Configuration;

var configuration = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string?>()
    {
        ["SomeKey"] = "SomeValue"
    })
    .Build();

Console.WriteLine(configuration["SomeKey"]);

// Outputs:
//   SomeValue

Met de voorgaande code wordt:

  • Hiermee maakt u een nieuw ConfigurationBuilder exemplaar.
  • Hiermee voegt u een verzameling sleutel-waardeparen toe aan de opbouwfunctie voor configuraties.
  • Roept de Build() methode aan om een IConfiguration exemplaar te maken.
  • Hiermee schrijft u de waarde van de SomeKey sleutel naar de console.

Hoewel in dit voorbeeld een in-memory configuratie wordt gebruikt, zijn er veel configuratieproviders beschikbaar, waarbij functionaliteit beschikbaar is voor bestandsgebaseerde, omgevingsvariabelen, opdrachtregelargumenten en andere configuratiebronnen. Zie Configuratieproviders in .NET voor meer informatie.

Alternatieve hostingbenadering

Uw apps doen meestal meer dan alleen leesconfiguratie. Ze gebruiken waarschijnlijk afhankelijkheidsinjectie, logboekregistratie en andere services. De .NET Generic Host-benadering wordt aanbevolen voor apps die gebruikmaken van deze services. U kunt in plaats daarvan een pakketverwijzing toevoegen aan Microsoft.Extensions.Hosting. Wijzig het Program.cs-bestand zodat het overeenkomt met de volgende code:

using Microsoft.Extensions.Hosting;

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

// Application code should start here.

await host.RunAsync();

De Host.CreateApplicationBuilder(String[]) methode biedt standaardconfiguratie voor de app in de volgende volgorde, van hoogste naar laagste prioriteit:

  1. Opdrachtregelargumenten met behulp van de opdrachtregelconfiguratieprovider.
  2. Omgevingsvariabelen met behulp van de configuratieprovider omgevingsvariabelen.
  3. App-geheimen wanneer de app wordt uitgevoerd in de Development omgeving.
  4. appsettings.json de JSON-configuratieprovider gebruiken.
  5. appsettings.Environment. json met behulp van de JSON-configuratieprovider. Bijvoorbeeld appsettings.Productie.json en appsettings.Ontwikkeling.json.
  6. ChainedConfigurationProvider : voegt een bestaande IConfiguration als bron toe.

Als u een configuratieprovider toevoegt, worden eerdere configuratiewaarden overschreven. De opdrachtregelconfiguratieprovider overschrijft bijvoorbeeld alle waarden van andere providers omdat deze het laatst is toegevoegd. Als SomeKey deze is ingesteld in zowel appsettings.json als de omgeving, wordt de omgevingswaarde gebruikt omdat deze is toegevoegd na appsettings.json.

Binding

Een van de belangrijkste voordelen van het gebruik van de .NET-configuratieabstracties is de mogelijkheid om configuratiewaarden te binden aan exemplaren van .NET-objecten. De JSON-configuratieprovider kan bijvoorbeeld worden gebruikt om appsettings.json bestanden toe te wijzen aan .NET-objecten en wordt gebruikt met afhankelijkheidsinjectie. Dit maakt het optiespatroon mogelijk, dat klassen gebruikt om sterk getypte toegang te bieden tot groepen gerelateerde instellingen. .NET-configuratie biedt verschillende abstracties. Houd rekening met de volgende interfaces:

  • IConfiguration: Vertegenwoordigt een set eigenschappen van de toepassingsconfiguratie van sleutel/waarde.
  • IConfigurationRoot: Vertegenwoordigt de hoofdmap van een IConfiguration hiërarchie.
  • IConfigurationSection: Vertegenwoordigt een sectie met toepassingsconfiguratiewaarden.

Deze abstracties zijn agnostisch voor hun onderliggende configuratieprovider (IConfigurationProvider). Met andere woorden, u kunt een IConfiguration exemplaar gebruiken om toegang te krijgen tot elke configuratiewaarde van meerdere providers.

De binder kan verschillende benaderingen gebruiken om configuratiewaarden te verwerken:

  • Directe deserialisatie (met behulp van ingebouwde conversieprogramma's) voor primitieve typen.
  • De TypeConverter voor een complex type wanneer het type er een heeft.
  • Weerspiegeling voor een complex type met eigenschappen.

Notitie

De binder heeft enkele beperkingen:

  • Eigenschappen worden genegeerd als ze privé-setters hebben of hun type niet kunnen worden geconverteerd.
  • Eigenschappen zonder bijbehorende configuratiesleutels worden genegeerd.

Bindinghiërarchieën

Configuratiewaarden kunnen hiërarchische gegevens bevatten. Hiërarchische objecten worden weergegeven met het gebruik van het : scheidingsteken in de configuratiesleutels. Als u toegang wilt krijgen tot een configuratiewaarde, gebruikt u het : teken om een hiërarchie te scheiden. Denk bijvoorbeeld aan de volgende configuratiewaarden:

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

De volgende tabel vertegenwoordigt voorbeeldsleutels en de bijbehorende waarden voor de voorgaande voorbeeld-JSON:

Sleutel Weergegeven als
"Parent:FavoriteNumber" 7
"Parent:Child:Name" "Example"
"Parent:Child:GrandChild:Age" 3

Basisvoorbeeld

Gebruik het ConfigurationBuilder type rechtstreeks om toegang te krijgen tot configuratiewaarden in hun basisvorm, zonder hulp van de algemene hostbenadering.

Tip

Het System.Configuration.ConfigurationBuilder type verschilt van het Microsoft.Extensions.Configuration.ConfigurationBuilder type. Al deze inhoud is specifiek voor de Microsoft.Extensions.* NuGet-pakketten en naamruimten.

Overweeg het volgende C#-project:

<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.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
  </ItemGroup>

</Project>

Het voorgaande projectbestand verwijst naar verschillende NuGet-configuratiepakketten:

Bekijk een voorbeeld van appsettings.json bestand:

{
    "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"
        ]
    }
}

Op basis van dit JSON-bestand ziet u nu een voorbeeld van een verbruikspatroon met behulp van de opbouwfunctie voor configuraties:

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

De voorgaande C#-code:

  • Instantieert een ConfigurationBuilder.
  • Hiermee voegt u het "appsettings.json" bestand toe dat wordt herkend door de JSON-configuratieprovider.
  • Hiermee worden omgevingsvariabelen toegevoegd die worden herkend door de configuratieprovider omgevingsvariabele.
  • Hiermee haalt u de vereiste "Settings" sectie en het bijbehorende Settings exemplaar op met behulp van het config exemplaar.

Het Settings object heeft de volgende vorm:

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!;
}

Basisvoorbeeld met hosting

Voor toegang tot de IConfiguration waarde kunt u opnieuw vertrouwen op het Microsoft.Extensions.Hosting NuGet-pakket. Maak een nieuwe consoletoepassing en plak de volgende inhoud van het projectbestand erin:

<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.Hosting" Version="8.0.0" />
  </ItemGroup>

</Project>

In het voorgaande projectbestand wordt gedefinieerd dat:

  • De toepassing is een uitvoerbaar bestand.
  • Een appsettings.json-bestand moet worden gekopieerd naar de uitvoermap wanneer het project wordt gecompileerd.
  • De Microsoft.Extensions.Hosting NuGet-pakketreferentie wordt toegevoegd.

Voeg het appsettings.json bestand toe aan de hoofdmap van het project met de volgende inhoud:

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

Vervang de inhoud van het bestand Program.cs door de volgende 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!

Wanneer u deze toepassing uitvoert, definieert het Host.CreateApplicationBuilder gedrag om de JSON-configuratie te detecteren en beschikbaar te maken via het IConfiguration exemplaar. Vanuit het host exemplaar kunt u de serviceprovider vragen om het IConfiguration exemplaar en deze vervolgens om waarden vragen.

Tip

Het gebruik van de onbewerkte IConfiguration instantie op deze manier, terwijl dit handig is, schaalt niet goed. Wanneer toepassingen complexer worden en de bijbehorende configuraties complexer worden, raden we u aan om het optiespatroon als alternatief te gebruiken.

Basisvoorbeeld met hosting en het gebruik van de indexeerfunctie-API

Houd rekening met dezelfde appsettings.json bestandsinhoud uit het vorige voorbeeld:

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

Vervang de inhoud van het bestand Program.cs door de volgende 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

De waarden worden geopend met behulp van de indexeerfunctie-API waarbij elke sleutel een tekenreeks is en de waarde een tekenreeks is. Configuratie ondersteunt eigenschappen, objecten, matrices en woordenlijsten.

Configuratieproviders

In de volgende tabel ziet u de configuratieproviders die beschikbaar zijn voor .NET Core-apps.

Provider Biedt configuratie van
Azure-app configuratieprovider Azure App Configuration
Azure Key Vault-configuratieprovider Azure Key Vault
Opdrachtregelconfiguratieprovider Opdrachtregelparameters
Aangepaste configuratieprovider Aangepaste bron
Configuratieprovider voor omgevingsvariabelen Omgevingsvariabelen
Bestandsconfiguratieprovider JSON-, XML- en INI-bestanden
Configuratieprovider voor sleutel per bestand Mapbestanden
Geheugenconfiguratieprovider Verzamelingen in het geheugen
App-geheimen (Secret Manager) Bestand in de gebruikersprofielmap

Tip

De volgorde waarin configuratieproviders worden toegevoegd, is belangrijk. Wanneer meerdere configuratieproviders worden gebruikt en meer dan één provider dezelfde sleutel opgeeft, wordt de laatste toegevoegde sleutel gebruikt.

Zie Configuratieproviders in .NET voor meer informatie over verschillende configuratieproviders.

Zie ook