Konfiguráció a .NET-ben

A .NET-ben a konfigurálást egy vagy több konfigurációszolgáltatósegítségével végezzük. A konfigurációszolgáltatók különböző konfigurációs források használatával olvassák be a kulcs-érték párok konfigurációs adatait:

  • Beállításfájlok, például appsettings.json
  • Környezeti változók
  • Azure Key Vault
  • Azure-alkalmazás konfigurációja
  • Parancssori paraméterek
  • Egyéni szolgáltatók (telepítve vagy létrehozva)
  • Címtárfájlok
  • Memóriabeli .NET-objektumok
  • Külső szolgáltatók

Jegyzet

A .NET-futtatókörnyezet konfigurálásával kapcsolatos információkért lásd .NET futtatókörnyezet konfigurációs beállításait.

Fogalmak és absztrakciók

Egy vagy több konfigurációs forrás miatt a IConfiguration típus egységes nézetet biztosít a konfigurációs adatokról. A konfiguráció írásvédett, és a konfigurációs minta nem programozott módon írható. A IConfiguration felület az összes konfigurációs forrás egyetlen ábrázolása, ahogyan az alábbi ábrán látható:

Az IConfiguration felület az összes konfigurációs forrás egyetlen ábrázolása.

Konzolalkalmazások konfigurálása

A dotnet új parancssablonjával vagy a Visual Studióval létrehozott .NET-konzolalkalmazások alapértelmezés szerint nem teszik elérhetővé a konfigurációs képességeket. Ha új .NET-konzolalkalmazásban szeretne konfigurációt hozzáadni, adjon hozzá egy csomaghivatkozást a Microsoft.Extensions.Configuration fájlhoz📦. Ez a csomag a .NET-alkalmazások konfigurációjának alapja. Ez biztosítja a ConfigurationBuilder és a kapcsolódó típusokat.

using Microsoft.Extensions.Configuration;

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

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

// Outputs:
//   SomeValue

Az előző kód:

  • Létrehoz egy új ConfigurationBuilder-példányt.
  • Kulcs-érték párok memóriabeli gyűjteményét adja hozzá a konfigurációszerkesztőhöz.
  • Meghívja a Build() metódust egy IConfiguration-példány létrehozásához.
  • A SomeKey kulcs értékét írja a konzolra.

Bár ez a példa memórián belüli konfigurációt használ, számos konfigurációszolgáltató érhető el, amelyek a fájlalapú, a környezeti változók, a parancssori argumentumok és más konfigurációs források funkcióit tárják fel. További információ: Konfigurációszolgáltatók a .NET-ben.

Alternatív üzemeltetési megközelítés

Az alkalmazások gyakran nem csak olvasási konfigurációt végeznek. Valószínűleg függőséginjektálást, naplózást és egyéb szolgáltatásokat fognak használni. A .NET Generic Host megközelítés ajánlott azoknak az alkalmazásoknak, amelyek ezeket a szolgáltatásokat használják. Ehelyett fontolja meg egy csomaghivatkozás hozzáadását a Microsoft.Extensions.Hosting szolgáltatáshoz📦. Módosítsa a Program.cs fájlt a következő kódnak megfelelően:

using Microsoft.Extensions.Hosting;

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

// Application code should start here.

await host.RunAsync();

A Host.CreateApplicationBuilder(String[]) metódus az alkalmazás alapértelmezett konfigurációját a következő sorrendben biztosítja, a legmagasabbtól a legalacsonyabb prioritásig:

  1. Parancssori argumentumok a parancssori konfigurációszolgáltatóval.
  2. Környezeti változók a konfigurációszolgáltatón keresztül.
  3. alkalmazás titkai, amikor az alkalmazás a Development környezetben fut.
  4. alkalmazásbeállításokat.Environment.json a JSON-konfigurációszolgáltató használatával. Például appsettings.Éles.json és appsettings.Fejlesztési.json.
  5. appsettings.json a JSON konfiguráció szolgáltatóhasználatával.
  6. ChainedConfigurationProvider: Meglévő IConfiguration-et ad hozzá forrásként.

A konfigurációszolgáltató hozzáadása felülírja a korábbi konfigurációs értékeket. Például a parancssori konfigurációszolgáltató felülbírálja a többi szolgáltató összes értékét, mert az utolsóként van hozzáadva. Ha a SomeKey be van állítva mind a appsettings.json-ben, mind a környezetben, akkor a környezeti érték kerül használatra, mert a appsettings.jsonután került hozzáadásra.

Kötelezettség

A .NET-konfiguráció absztrakcióinak egyik fő előnye, hogy a konfigurációs értékeket a .NET-objektumok példányaihoz köti . A JSON-konfigurációszolgáltató például felhasználható arra, hogy appsettings.json fájlokat .NET-objektumokra képezzünk le és függőséginjektálással használják. Ez lehetővé teszi a beállításmintát, amely osztályok alkalmazásával biztosít erős típusú hozzáférést a kapcsolódó beállítások csoportjaihoz. Az alapértelmezett kötő reflexióalapú, de létezik egy forrásgenerátor alternatíva, amely könnyen engedélyezhető.

A .NET-konfiguráció különböző absztrakciókat biztosít. Vegye figyelembe a következő felületeket:

Ezek az absztrakciók a mögöttes konfigurációszolgáltató (IConfigurationProvider) számára agnosztikusak. Más szóval egy IConfiguration-példány használatával több szolgáltató bármely konfigurációs értékét elérheti.

A kötőanyag különböző módszerekkel dolgozhatja fel a konfigurációs értékeket:

  • Közvetlen deszerializálás (beépített konverterek használatával) primitív típusokhoz.
  • Összetett típusok esetén a TypeConverter, ha a típus rendelkezik ilyennel.
  • Tulajdonságokkal rendelkező összetett típus tükröződése.

Jegyzet

A kötőanyag néhány korlátozással rendelkezik:

  • A tulajdonságok figyelmen kívül lesznek hagyva, ha privát beállítóik vannak, vagy a típusuk nem konvertálható.
  • A megfelelő konfigurációs kulcsok nélküli tulajdonságok figyelmen kívül lesznek hagyva.

Kötési hierarchiák

A konfigurációs értékek hierarchikus adatokat tartalmazhatnak. A hierarchikus objektumok a : elválasztó használatával jelennek meg a konfigurációs kulcsokban. Egy konfigurációs érték eléréséhez használja a : karaktert a hierarchia elválasztásához. Vegyük például a következő konfigurációs értékeket:

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

Az alábbi táblázat az előző JSON-példához tartozó példakulcsokat és azok megfelelő értékeit jelöli:

Kulcs Érték
"Parent:FavoriteNumber" 7
"Parent:Child:Name" "Example"
"Parent:Child:GrandChild:Age" 3

Speciális kötési forgatókönyvek

A konfigurációs kötő bizonyos típusokkal végzett munka során sajátos viselkedési módokkal és korlátozásokkal rendelkezik. Ez a szakasz a következő alszakaszokat tartalmazza:

Kötés szótárakhoz

Ha egy Dictionary<TKey,TValue> konfigurációt köt egy olyan helyzethez, ahol az érték változtatható gyűjteménytípus (például tömbök vagy listák), az ismételt kötések ugyanahhoz a kulcshoz kibővítik a gyűjtemény elemeit ahelyett, hogy lecserélnék őket.

Az alábbi példa ezt a viselkedést mutatja be:

IConfiguration config = new ConfigurationBuilder()
    .AddInMemoryCollection()
    .Build();

config["Queue:0"] = "Value1";
var dict = new Dictionary<string, string[]>() { { "Queue", new[] { "InitialValue" } } };

Console.WriteLine("=== Dictionary Binding with Collection Values ===");
Console.WriteLine($"Initially: {string.Join(", ", dict["Queue"])}");

// In .NET 7+, binding extends the collection instead of replacing it.
config.Bind(dict);
Console.WriteLine($"After Bind: {string.Join(", ", dict["Queue"])}");

config["Queue:1"] = "Value2";
config.Bind(dict);
Console.WriteLine($"After 2nd Bind: {string.Join(", ", dict["Queue"])}");

További információ: A szótárhoz való kötés konfigurációja kibővíti az értékeket.

Szótárkulcsok kettőspontokkal

A kettőspont (:) karakter hierarchiaelválasztóként van fenntartva a konfigurációs kulcsokban. Ez azt jelenti, hogy nem használhat kettőspontot a szótárkulcsokban a konfiguráció kötésekor. Ha a kulcsok kettőspontokat (például URL-címeket vagy más formázott azonosítókat) tartalmaznak, a konfigurációs rendszer a literális karakterek helyett hierarchiaútvonalakként értelmezi őket. Fontolja meg a következő alternatív megoldásokat:

  • Használjon alternatív elválasztó karaktereket (például dupla aláhúzásjeleket __) a konfigurációs kulcsokban, és szükség esetén programozott módon alakítsa át őket.
  • Manuálisan deszerializálja a konfigurációt nyers JSON használatával, System.Text.Json vagy egy hasonló könyvtár használatával, amely támogatja a kettőspontokat a kulcsokban.
  • Hozzon létre egy egyéni leképezési réteget, amely kettőspontokkal lefordítja a biztonságos kulcsokat a kívánt kulcsokra.

IReadOnly* típusokhoz való csatlakozás

A konfigurációs kötés nem támogatja közvetlenül a IReadOnlyList<T>, IReadOnlyDictionary<TKey, TValue> vagy más írásvédett gyűjteményi felületekhez való kötést. Ezek a felületek hiányoznak azokat a mechanizmusokat, amelyekre a kötőanyagnak szüksége van a gyűjtemények feltöltéséhez.

Az írásvédett gyűjteményekkel való munkához használjon megváltoztatható típusokat a kötőprogram által feltöltött tulajdonságokhoz, majd ezeket tegye elérhetővé írásvédett felületek formájában a felhasználók számára.

Console.WriteLine("=== IReadOnly* Types (NOT Directly Supported) ===");

var readonlyConfig = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string?>
    {
        ["Settings:Values:0"] = "Item1",
        ["Settings:Values:1"] = "Item2",
        ["Settings:Values:2"] = "Item3",
    })
    .Build();

// This class uses List<string> for binding, exposes as IReadOnlyList<string>.
var settings = new SettingsWithReadOnly();
readonlyConfig.GetSection("Settings").Bind(settings);

Console.WriteLine("Values bound to mutable List, exposed as IReadOnlyList:");
foreach (var value in settings.ValuesReadOnly)
{
    Console.WriteLine($"  {value}");
}

A konfigurációs osztály implementálása:

class SettingsWithReadOnly
{
    // Use mutable type for binding
    public List<string> Values { get; set; } = [];

    // Expose as read-only for consumers
    public IReadOnlyList<string> ValuesReadOnly => Values;
}

Ez a módszer lehetővé teszi, hogy a kötőanyag feltöltse a mutable-t List<string> , miközben megváltoztathatatlan felületet ad a fogyasztóknak IReadOnlyList<string>.

Összekapcsolás paraméteres konstruktorokkal

A .NET 7-től kezdve a konfigurációkötő egyetlen nyilvános paraméteres konstruktorral támogatja a típusok kötését. Ez lehetővé teszi, hogy a nem módosítható típusok és rekordok közvetlenül a konfigurációból legyenek feltöltve:

Console.WriteLine("=== Parameterized Constructor Binding ===");

var ctorConfig = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string?>
    {
        ["AppSettings:Name"] = "MyApp",
        ["AppSettings:MaxConnections"] = "100",
        ["AppSettings:Timeout"] = "30"
    })
    .Build();

// Binding to a type with a single parameterized constructor
var appSettings = ctorConfig.GetSection("AppSettings").Get<AppSettings>();
if (appSettings != null)
{
    Console.WriteLine($"Name: {appSettings.Name}");
    Console.WriteLine($"MaxConnections: {appSettings.MaxConnections}");
    Console.WriteLine($"Timeout: {appSettings.Timeout}");
}

A nem módosítható beállításosztály:

// Immutable type with single parameterized constructor.
class AppSettings
{
    public string Name { get; }
    public int MaxConnections { get; }
    public int Timeout { get; }

    public AppSettings(string name, int maxConnections, int timeout)
    {
        Name = name;
        MaxConnections = maxConnections;
        Timeout = timeout;
    }
}

Fontos

A kötőanyag csak egyetlen nyilvános paraméteres konstruktorral rendelkező típusokat támogat. Ha egy típus több nyilvános paraméteres konstruktorral rendelkezik, a kötés nem tudja meghatározni, hogy melyiket használja, és a kötés sikertelen lesz. Használjon egyetlen paraméteres konstruktort vagy paraméter nélküli konstruktort tulajdonsághalmazokkal.

Egyszerű példa

Ha alapszintű konfigurációs értékeket szeretne elérni az általános gazdagép megközelítése nélkül, használja a ConfigurationBuilder típust közvetlenül.

Tipp

A System.Configuration.ConfigurationBuilder típus eltér a Microsoft.Extensions.Configuration.ConfigurationBuilder típustól. Minden tartalom a Microsoft.Extensions.* NuGet-csomagokra és névterekre vonatkozik.

Fontolja meg a következő C#-projektet:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.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="10.0.7" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.7" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.7" />
  </ItemGroup>

</Project>

Az előző projektfájl több konfigurációs NuGet-csomagra hivatkozik:

Vegyünk egy példát appsettings.json fájlra:

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

A JSON-fájl alapján most íme egy példa fogyasztási minta a konfigurációszerkesztő közvetlen használatával:

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

Az előző C# kód:

  • Példányosít egy ConfigurationBuilder.
  • Hozzáadja a JSON-konfigurációszolgáltató által felismerendő "appsettings.json" fájlt.
  • Környezeti változókat ad hozzá, amelyeket a környezeti változók konfigurációszolgáltatója felismer.
  • Megkapja a szükséges "Settings" szakaszt és a megfelelő Settings példányt a config-példány használatával.

A Settings objektum a következőképpen van formázva:

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

Alapszintű példa üzemeltetéssel

A IConfiguration érték eléréséhez újra támaszkodhat a Microsoft.Extensions.Hosting NuGet-csomagra. Hozzon létre egy új konzolalkalmazást, és illessze be a következő projektfájl tartalmát:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.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="10.0.7" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.7" />
  </ItemGroup>

</Project>

Az előző projektfájl a következőket határozza meg:

  • Az alkalmazás végrehajtható.
  • A appsettings.json fájlokat a projekt fordításakor a kimeneti könyvtárba kell másolni.
  • A rendszer hozzáadja a Microsoft.Extensions.Hosting NuGet-csomaghivatkozást.

Adja hozzá a appsettings.json fájlt a projekt gyökeréhez a következő tartalommal:

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

Cserélje le a Program.cs fájl tartalmát a következő C#-kódra:

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!

Az alkalmazás futtatásakor a Host.CreateApplicationBuilder határozza meg a JSON-konfiguráció felderítésének és a IConfiguration-példányon keresztüli elérhetővé ciójának viselkedését. A host példányból kérheti a szolgáltatótól a IConfiguration-példányt, majd kérheti az értékeket.

Tipp

Ha így használja a nyers IConfiguration-példányt, bár kényelmes, nem skálázható túl jól. Amikor az alkalmazások összetettebbé válnak, és a hozzájuk tartozó konfigurációk összetettebbé válnak, javasoljuk, hogy alternatívaként használja a beállításmintát.

Egyszerű példa az indexelő API üzemeltetésére és használatára

Vegye figyelembe az előző példában szereplő appsettings.json fájltartalmat:

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

Cserélje le a Program.cs fájl tartalmát a következő C#-kódra:

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

Az értékek az indexelő API-val érhetők el, ahol minden kulcs egy sztring, az érték pedig egy sztring. A konfiguráció támogatja a tulajdonságokat, objektumokat, tömböket és szótárakat.

Konfigurációszolgáltatók

Az alábbi táblázat a .NET Core-alkalmazások számára elérhető konfigurációszolgáltatókat mutatja be.

Konfigurációszolgáltató Konfigurációt biztosít a
Azure-alkalmazás konfigurációja Azure App Configuration
Azure Key Vault Azure Key Vault
Parancssori felület Parancssori paraméterek
Egyéni Egyéni forrás
Környezeti változók Környezeti változók
fájl JSON-, XML- és INI-fájlok
Egyedi kulcs minden fájlhoz Címtárfájlok
memória Memóriában tárolt gyűjtemények
Alkalmazás titkos kódjai (titkos kódkezelő) Fájl a felhasználói profil könyvtárában

Tipp

A konfigurációszolgáltatók hozzáadásának sorrendje számít. Ha több konfigurációszolgáltatót használ, és egynél több szolgáltató adja meg ugyanazt a kulcsot, a rendszer az utolsó hozzáadott kulcsot használja.

További információ a különböző konfigurációszolgáltatókról: .NET-konfigurációs szolgáltatók.

Lásd még: