Februar 2016

Band 31, Nummer 2

.NET-Grundlagen – Konfiguration in .NET Core

Von Mark Michaelis

Kurz vor Drucklegung hat Microsoft für ASP.NET 5 und dazugehörige Stapel Namensänderungen angekündigt. ASP.NET 5 heißt jetzt ASP.NET Core 1.0. Entity Framework (EF) 7 heißt jetzt Entity Framework (EF) Core 1.0. Die ASP.NET 5- und EF7-Pakete und Namespaces ändern sich, doch ansonsten hat die neue Namensgebung keine Auswirkung auf die Lektionen in diesem Artikel.

Mark MichaelisWenn Sie mit ASP.NET 5 arbeiten, haben Sie bestimmt schon die neue Konfigurationsunterstützung auf dieser Plattform bemerkt, die in der „Microsoft.Extensions.Configuration“-Auflistung von NuGet-Paketen verfügbar ist. Die neue Konfiguration lässt eine List von Name-Wert-Paaren zu, die in einer Hierarchie mit mehreren Ebenen gruppiert werden können. Angenommen, Sie haben eine Einstellung in „SampleApp:Users:Inigo­Montoya:MaximizeMainWindow“ und eine andere in „SampleApp:AllUsers:Default:MaximizeMainWindow“ gespeichert. Jeder gespeicherte Wert ist einer Zeichenfolge zugeordnet, und es gibt eine integrierte Bindungsunterstützung, die Ihnen das Deserialisieren von Einstellungen in ein benutzerdefiniertes POCO-Objekt ermöglicht. Diejenigen von Ihnen, die bereits mit der neuen Konfigurations-API vertraut sind, sind ihr wahrscheinlich erstmals in ASP.NET 5 begegnet. Doch die API ist keineswegs nur auf ASP.NET beschränkt. Tatsächlich wurden alle Listen in diesem Artikel in einem Visual Studio 2015-Komponententestprojekt mit Microsoft .NET Framework 4.5.1 erstellt, das auf „Microsoft.Extensions.Configuration“-Pakete aus ASP.NET 5 RC1 verweist. (Den Quellcode finden Sie unter gitHub.com/IntelliTect/Articles.)

Die Konfigurations-API unterstützt Konfigurationsanbieter für speicherresidente .NET-Objekte, INI-, JSON - und XML-Dateien, Befehlszeilenargumente, Umgebungsvariablen, einen verschlüsselten Benutzerspeicher und alle benutzerdefinierten Anbieter, die Sie erstellen. Wenn Sie in Ihrer Konfiguration JSON-Dateien nutzen möchten, müssen Sie bloß das NuGet-Paket „Microsoft.Extensions.Configuration.Json“ hinzufügen. Wenn Sie anschließend das Bereitstellen von Konfigurationsinformationen über die Befehlszeile zulassen möchten, fügen Sie einfach das NuGet-Paket „Microsoft.Extensions.Configuration.CommandLine“ hinzu, entweder zusätzlich oder anstelle anderer Konfigurationsverweise. Wenn keiner der integrierten Konfigurationsanbieter Ihre Anforderungen erfüllt, können Sie Ihren eigenen erstellen, indem Sie die Schnittstellen in „Microsoft.Extensions.Configuration.Abstractions“ implementieren.

Abrufen von Konfigurationseinstellungen

Um sich mit dem Abrufen von Konfigurationseinstellungen vertraut zu machen, werfen Sie einen Blick auf Abbildung 1.

Abbildung 1: Grundlegende Konfiguration mithilfe der Erweiterungsmethoden „InMemoryConfigurationProvider“ und „ConfigurationBinder“

public class Program
{
  static public string DefaultConnectionString { get; } =
    @"Server=(localdb)\\mssqllocaldb;Database=SampleData-0B3B0919-C8B3-481C-9833-
    36C21776A565;Trusted_Connection=True;MultipleActiveResultSets=true";
  static IReadOnlyDictionary<string, string> DefaultConfigurationStrings{get;} =
    new Dictionary<string, string>()
    {
      ["Profile:UserName"] = Environment.UserName,
      [$"AppConfiguration:ConnectionString"] = DefaultConnectionString,
      [$"AppConfiguration:MainWindow:Height"] = "400",
      [$"AppConfiguration:MainWindow:Width"] = "600",
      [$"AppConfiguration:MainWindow:Top"] = "0",
      [$"AppConfiguration:MainWindow:Left"] = "0",
    };
  static public IConfiguration Configuration { get; set; }
  public static void Main(string[] args = null)
  {
    ConfigurationBuilder configurationBuilder =
      new ConfigurationBuilder();
      // Add defaultConfigurationStrings
      configurationBuilder.AddInMemoryCollection(
        DefaultConfigurationStrings);
      Configuration = configurationBuilder.Build();
      Console.WriteLine($"Hello {Configuration["Profile:UserName"]}");
      ConsoleWindow consoleWindow =
        Configuration.Get<ConsoleWindow>("AppConfiguration:MainWindow");
      ConsoleWindow.SetConsoleWindow(consoleWindow);
  }
}

Der Zugriff auf die Konfiguration beginnt mit einer Instanz von „ConfigurationBuilder“, einer Klasse, die im NuGet-Paket „Microsoft.Extensions.Configuration“ verfügbar ist. Ausgehend von der „ConfigurationBuilder“-Instanz können Sie Anbieter direkt mithilfe von „IConfigurationBuilder“-Erweiterungsmethoden wie „AddInMemoryCollection“ hinzufügen (siehe Abbildung 1). Diese Methode verwendet eine „Dictionary<string,string>“-Instanz der Name-Wert-Paare der Konfiguration, die Sie zum Initialisieren des Konfigurationsanbieters nutzt, bevor dieser der „ConfigurationBuilder“-Instanz hinzugefügt wird. Nachdem der Konfigurations-Generator „konfiguriert“ wurde, rufen Sie dessen „Build“-Methode zum Abrufen der Konfiguration ab.

Wie bereits erwähnt, ist eine Konfiguration eine hierarchische Liste von Name-Wert-Paaren, in denen die Knoten durch einen Doppelpunkt getrennt sind. Um also einen bestimmten Wert abzurufen, greifen Sie mithilfe des Schlüssels des entsprechenden Elements auf den Konfigurations-Indexer zu:

Console.WriteLine($"Hello {Configuration["Profile:UserName"]}");

Doch das Zugreifen auf einen Wert ist nicht bloß auf das Abrufen von Zeichenfolgen beschränkt. Sie können beispielsweise Werte über die „Get<T>“-Erweiterungsmethoden von ConfigurationBinder abrufen. Um z. B. die Puffergröße des Bildschirms des Hauptfensters abzurufen, können Sie Folgendes verwenden:

Configuration.Get<int>("AppConfiguration:MainWindow:ScreenBufferSize", 80);

Diese Bindungsunterstützung erfordert einen Verweis auf das NuGet-Paket „Microsoft.Exten­sions.Configuration.Binder“.

Wie Sie sehen, folgt auf den Schlüssel ein optionales Argument, für das Sie einen zurückzugebenden Standardwert angeben können, sollte der Schlüssel nicht vorhanden sein. (Ohne den Standardwert wird der Rückgabe „default(T)“ zugewiesen, ohne dass, wie vielleicht erwartet, eine Ausnahme ausgelöst wird.)

Konfigurationswerte sind nicht auf Skalare begrenzt. Sie können POCO-Objekte oder sogar ganze Objektgraphen abrufen. Zum Abrufen einer „ConsoleWindow“-Instanz, deren Member dem Konfigurationsabschnitt „AppConfiguration:MainWindow“ zugeordnet sind, wird in Abbildung 1 Folgendes angegeben:

ConsoleWindow consoleWindow =
  Configuration.Get<ConsoleWindow>("AppConfiguration:MainWindow")

Alternativ können Sie einen Konfigurationsgraphen wie AppConfiguration definieren (siehe Abbildung 2).

Abbildung 2: Beispiel eines Konfigurationsobjektgraphen

class AppConfiguration
{
  public ProfileConfiguration Profile { get; set; }
   public string ConnectionString { get; set; }
  public WindowConfiguration MainWindow { get; set; }
  public class WindowConfiguration
  {
    public int Height { get; set; }
    public int Width { get; set; }
    public int Left { get; set; }
    public int Top { get; set; }
  }
  public class ProfileConfiguration
  {
    public string UserName { get; set; }
  }
}
public static void Main()
{
  // ...
  AppConfiguration appConfiguration =
    Program.Configuration.Get<AppConfiguration>(
      nameof(AppConfiguration));
  // Requires referencing System.Diagnostics.TraceSource in Corefx
  System.Diagnostics.Trace.Assert(
    600 == appConfiguration.MainWindow.Width);
}

Mit einem solchen Objektgraphen können Sie Ihre Konfiguration vollständig oder teilweise mit einer stark typisierten Objekthierarchie definieren, mit deren Hilfe Sie anschließend Ihre Einstellungen alle auf einmal abrufen können.

Mehrere Konfigurationsanbieter

Der InMemoryConfigurationProvider eignet sich besonders zum Speichern von Standardwerten oder möglicherweise berechneten Werten. Doch bei nur diesem Anbieter fällt weiter der Aufwand für das Abrufen der Konfiguration und ihr Laden in eine „Dictionary<string,string>“-Instanz an, bevor die Registrierung bei ConfigurationBuilder erfolgt. Glücklicherweise gibt es mehrere integrierte Konfigurationsanbieter, so z. B. drei dateibasierte Anbieter (XmlConfigurationProvider, IniConfigurationProvider and JsonConfigurationProvider), einen Umgebungsvariablenanbieter (EnvironmentVariableConfigurationProvider) und einen Anbieter von Befehlszeilenargumenten (CommandLineConfigurationProvider). Darüber hinaus können diese Anbieter entsprechend Ihrer Anwendungslogik kombiniert und abgestimmt werden. Angenommen, Sie möchten Konfigurationseinstellungen mit der folgenden aufsteigenden Priorität angeben:

  • InMemoryConfigurationProvider
  • JsonFileConfigurationProvider für Config.json
  • JsonFileConfigurationProvider für Config.Production.json
  • EnvironmentVariableConfigurationProvider
  • CommandLineConfigurationProvider

Die Standardkonfigurationswerte können also in Code gespeichert werden. Als Nächstes kann die Datei „config.json“ gefolgt von der Datei „Config.Production.json“ die für InMemory angegebenen Werte überschreiben, sodass spätere Anbieter wie der für JSON Vorrang vor etwaigen überlappenden Werten haben. Wenn Sie im nächsten Schritt bereitstellen, gibt es ggf. benutzerdefinierte Konfigurationswerte, die in Umgebungsvariablen gespeichert sind. Anstatt „Config.Production.json“ hartzucodieren, können Sie die Umgebungseinstellung aus einer Windows-Umgebungsvariablen abrufen und auf die bestimmte Datei (z. B. „Config.Test.Json“) zugreifen, die die Umgebungsvariable bestimmt. (Verzeihen Sie bitte die Mehrdeutigkeit des Begriffs „Umgebungseinstellung“ in Bezug auf Produktions-, Test, Präproduktions- oder Entwicklungsumgebungen im Vergleich mit Windows- Umgebungsvariablen wie %USERNAME% oder %USERDOMAIN%.) Schließlich können Sie beliebige zuvor bereitgestellte Einstellungen über die Befehlszeile angeben (oder überschreiben), ggf. als einmalige Änderung, um beispielsweise die Protokollierung zu aktivieren.

Zum Angeben der einzelnen Anbieter fügen Sie sie dem Konfigurations-Generator hinzu (über die Erweiterungsmethode der AddX-Fluent-API), wie in Abbildung 3 gezeigt.

Abbildung 3: Hinzufügen mehrerer Konfigurationsanbieter (der zuletzt angegebene hat Vorrang)

public static void Main(string[] args = null)
{
  ConfigurationBuilder configurationBuilder =
    new ConfigurationBuilder();
  configurationBuilder
    .AddInMemoryCollection(DefaultConfigurationStrings)
    .AddJsonFile("Config.json",
      true) // Bool indicates file is optional
    // "EssentialDotNetConfiguartion" is an optional prefix for all
    // environment configuration keys, but once used,
    // only environment variables with that prefix will be found        
    .AddEnvironmentVariables("EssentialDotNetConfiguration")
    .AddCommandLine(
      args, GetSwitchMappings(DefaultConfigurationStrings));
  Console.WriteLine($"Hello {Configuration["Profile:UserName"]}");
  AppConfiguration appConfiguration =
    Configuration.Get<AppConfiguration>(nameof(AppConfiguration));
}
static public Dictionary<string,string> GetSwitchMappings(
  IReadOnlyDictionary<string, string> configurationStrings)
{
  return configurationStrings.Select(item =>
    new KeyValuePair<string, string>(
      "-" + item.Key.Substring(item.Key.LastIndexOf(':')+1),
      item.Key))
      .ToDictionary(
        item => item.Key, item=>item.Value);
}

Für den JsonConfigurationProvider können Sie anfordern, dass die Datei vorhanden oder optional ist (deshalb der zusätzliche optionale Parameter für AddJsonFile). Wird kein Parameter angegeben, ist die Datei erforderlich, und die Ausnahme „System.IO.FileNotFoundException“ wird ausgelöst, falls sie nicht gefunden wird. Angesichts des hierarchischen Aufbaus von JSON passt die Konfiguration optimal zur Konfigurations-API (siehe Abbildung 4).

Abbildung 4: JSON-Konfigurationsdaten für den JsonConfigurationProvider

{
  "AppConfiguration": {
    "MainWindow": {
      "Height": "400",
      "Width": "600",
      "Top": "0",
      "Left": "0"
    },
    "ConnectionString":
      "Server=(localdb)\\\\mssqllocaldb;Database=Database-0B3B0919-C8B3-481C-9833-
      36C21776A565;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Der CommandLineConfigurationProvider erfordert das Angeben der Argumente, wenn er beim Konfigurations-Generator registriert wird. Argumente werden als Zeichenfolgenarray von Name-Wert-Paaren angegeben, wobei jedes Paar das Format /<Name>=<Wert> hat, bei dem das Gleichheitszeichen erforderlich ist. Der führende Schrägstrich ist auch erforderlich, doch der zweite Parameter der Funktion „AddCommandLine(string[] args, Dictionary<string,string> switchMappings)“ ermöglicht Ihnen das Angeben von Aliasen, vor die als Präfix entweder „-“ oder „--“ gesetzt werden muss. Ein Wörterbuch mit Werten ermöglicht beispielsweise das Laden der Befehlszeile „program.exe -LogFile="c:\programdata\Application Data\Program.txt“ in das Konfigurationselement „AppConfiguration:LogFile“:

["-DBConnectionString"]="AppConfiguration:ConnectionString",
  ["-LogFile"]="AppConfiguration:LogFile"

Vor dem Abschließen der Konfigurationsgrundlagen hier noch verschiedene zu beachtende Punkte:

  • Der CommandLineConfigurationProvider weist mehrere Merkmale auf, die sich mithilfe von IntelliSense nicht unbedingt erschließen und die Sie kennen sollten:
    • Die CommandLineConfigurationProvider-Einstellung „switchMappings“ lässt nur das Switch-Präfix „-“ oder „--“ zu. Selbst ein Schrägstrich(/) ist nicht als Switch-Parameter zulässig. Dies hindert Sie, Aliase für Schrägstrich-Switches mittels Switch-Zuordnungen anzugeben.
    • Für CommandLineConfigurationProviders sind keine Switch-basierten Befehlszeilenargumente zulässig. Dies sind Argumente ohne zugewiesenen Wert. Das Angeben des Schlüssels „/Maximize“ ist beispielsweise nicht erlaubt.
    • Während Sie Argumente für „Main“ an eine neue „CommandLineConfigurationProvider“-Instanz übergeben können, ist es nicht möglich, Environment.GetCommandLineArgs zu übergeben, ohne zuvor den Prozessnamen zu entfernen. (Beachten Sie, dass sich Environment.GetCommandLineArgs anders verhält, wenn ein Debugger angefügt ist. Insbesondere Namen von ausführbaren Dateien werden in einzelne Argument aufgeteilt, wenn kein Debugger angefügt ist. Siehe „itl.ty\GetCommandLineGotchas“).
    • Eine Ausnahme wird ausgelöst, wenn Sie über eine Befehlszeile das Switch-Präfix „-“ oder „--“ angeben, für das es keine entsprechende Switch-Zuordnung gibt.
  • Wenngleich Konfigurationen aktualisiert werden können (Configuration["Profile:UserName"]="Inigo Montoya"), wird der aktualisierte Wert nicht beständig in den Ursprungsspeicher zurückgespeichert. Wenn Sie z. B. einem JSON-Anbieter einen Konfigurationswert zuweisen, wird die JSON-Datei nicht aktualisiert. Gleichfalls wird eine Umgebungsvariable nicht aktualisiert, wenn ihr Konfigurationselement zugewiesen wird.
  • Der EnvironmentVariableConfigurationProvider lässt optional die Angabe eines Schlüsselpräfixes zu. In diesen Fällen lädt der Anbieter nur die Umgebungsvariablen mit dem angegebenen Präfix. Auf diese Weise können Sie die Konfigurationseinträge automatisch auf diejenigen im „Abschnitt“ (section) einer Umgebungsvariablen oder allgemeiner begrenzen, die für Ihre Anwendung relevant sind.
  • Umgebungsvariablen mit einem Doppelpunkt als Trennzeichen werden unterstützt. Beispielsweise ist das Zuweisen von „SET AppConfiguration:ConnectionString=Console“ über die Befehlszeile erlaubt.
  • Bei allen Konfigurationsschlüsseln (-namen) wird Groß-/Kleinschreibung nicht unterschieden.
  • Jeder Anbieter befindet sich in seinem eigenen NuGet-Paket, wobei der NuGet-Paketname dem Anbieter entspricht: Microsoft.Extensions.Configuration.CommandLine, Microsoft.Extensions.Configuration.EnvironmentVariables, Microsoft.Extensions.Configuration.Ini, Microsoft.Extensions.Configuration.Json und Microsoft.Extensions.Configuration.Xml.

Grundlegendes zur objektorientierten Struktur

Sowohl die Modularität als auch die objektorientierte Struktur der Konfigurations-API sind gut durchdacht. Geboten werden auffindbare, modulare und einfach erweiterbare Klassen und Schnittstellen, mit denen sich gut arbeiten lässt (siehe Abbildung 5).

Klassenmodell für Konfigurationsanbieter
Abbildung 5: Klassenmodell für Konfigurationsanbieter

Jeder Typ von Konfigurationsmechanismus hat eine entsprechende Konfigurationsanbieterklasse, die IConfigurationProvider implementiert. Bei der Mehrzahl integrierter Anbieterimplementierungen basiert die Implementierung auf einer Ableitung von ConfigurationBuilder und nicht auf der Nutzung benutzerdefinierter Implementierungen für alle Schnittstellenmethoden. Deshalb ist es vielleicht überraschend, dass es in Abbildung 1 keinen direkten Verweis auf einen der Anbieter gibt. Der Grund ist, dass anstatt jeden Anbieter manuell zu instanziieren und bei der „Add“-Methode der „ConfigurationBuilder“-Klasse zu registrieren, das NuGet-Paket jedes Anbieters eine statische Erweiterungsklasse mit „IConfigurationBuilder“-Erweiterungsmethoden enthält. (Der Name der Erweiterungsklasse wird im Allgemeinen vom Suffix „ConfigurationExtensions“ bestimmt.) Mithilfe der Erweiterungsklassen können Sie beginnen, direkt in ConfigurationBuilder (der „IConfigurationBuilder“ implementiert) auf die Konfigurationsdaten zuzugreifen und die Ihrem Anbieter zugeordnete Erweiterungsmethode direkt aufzurufen. Die „JasonConfigurationExtensions“-Klasse fügt z. B. die „AddJsonFile“-Erweiterungsmethoden zu IConfigurationBuilder so hinzu, dass Sie die JSON-Konfiguration mit einem Aufruf von „Configuration­Builder.AddJsonFile(fileName, optional).Build();“ hinzufügen können.

Zumeist gilt, dass sobald Sie eine Konfiguration haben, Sie über alles verfügen, was Sie zum Abrufen von Werten brauchen.

IConfiguration bietet einen Zeichenfolgenindexer, mit dessen Hilfe Sie jeden gewünschten Konfigurationswert mithilfe des Schlüssels für den Zugriff auf das Element abrufen können, nach dem Sie suchen. Sie können eine gesamte Gruppe von Einstellungen (Abschnitt genannt) mit den Methoden „GetSection“ und „GetChildren“ abrufen (was davon abhängt, ob Sie einen Drilldown in eine weitere Ebene der Hierarchie ausführen möchten). Beachten Sie, dass die Abschnitte mit den Konfigurationselementen das Abrufen der folgenden Einstellungen ermöglichen:

  • Schlüssel: das letzte Element des Namens.
  • Pfad: der vollständige Name, der auf das Stammverzeichnis des aktuellen Speicherorts zeigt.
  • Wert: der in der Konfigurationseinstellung gespeicherte Konfigurationswert.
  • Wert als Objekt: über ConfigurationBinder können Sie ein POCO-Objekt abrufen, das dem Konfigurationsabschnitt (und möglicherweise seinen untergeordneten Elementen) entspricht, auf den Sie zugreifen. So funktioniert beispielsweise „Configuration.Get<AppConfiguration>(nameof(App­Configuration))“ in Abbildung 3.
  • IConfigurationRoot bietet eine „Reload“-Funktion, die Ihnen das Neuladen von Werten zum Aktualisieren der Konfiguration ermöglicht. ConfigurationRoot (das „IConfigurationRoot“ implementiert) bietet eine „GetReloadToken“-Methode, mit der Sie sich für Benachrichtigungen bei Erfolgen eines Neuladevorgangs (und möglichen Wertänderung) registrieren können.

Verschlüsselte Einstellungen

Gelegentlich möchten Sie Einstellungen abrufen, die verschlüsselt anstatt in Klartext gespeichert sind. Dies ist z. B. wichtig, wenn Sie OAuth-Anwendungsschlüssel oder -Token bzw. Anmeldeinformationen für eine Datenbankverbindungs-Zeichenfolge speichern. Das „Microsoft.Extensions.Configuration“-System bietet glücklicherweise integrierte Unterstützung für das Lesen verschlüsselter Werte. Für den Zugriff auf den sicheren Speicher müssen Sie einen Verweis auf das NuGet-Paket „Microsoft.Extensions.Configuration.User­Secrets“ hinzufügen. Nach dessen Hinzufügen verfügen Sie über eine neue „IConfigurationBuilder.AddUserSecrets“-Erweiterungsmethode, die ein Zeichenfolgenelement eines Konfigurationselements namens „userSecretsId“ verwendet (das in Ihrer Datei „project.json“ gespeichert ist). Wie erwartet, können Sie nach Hinzufügen der „UserSecrets“-Konfiguration zum Konfigurations-Generator beginnen, verschlüsselte Werte abzurufen, auf die nur Benutzer, denen die Einstellungen zugeordnet sind, zugreifen können.

Offenkundig ist das Abrufen von Einstellungen auf gewisse Weise sinnfrei, wenn Sie sie nicht auch festlegen können. Verwenden Sie hierfür das Tool „user-secret.cmd“ wie folgt:

user-secret set <secretName> <value> [--project <projectPath>]

Die Option „--project“ ermöglicht Ihnen das Zuordnen der Einstellung zum „userSecretsId“-Wert, der in Ihrer Datei „project.json“ gespeichert ist (die standardmäßig vom ASP.NET 5-Assistenten für neue Projekte erstellt wird). Wenn Sie das Tool „user-secret“ nicht haben, müssen Sie es über die Entwicklereingabeaufforderung des DNX-Hilfsprogramms (derzeit „dnu.exe“) hinzufügen.

Weitere Informationen zur Konfigurationsoption „user-secret“ finden Sie im Artikel „Safe Storage of Application Secrets“ von Rick Anderson und David Roth unter bit.ly/1mmnG0L.

Zusammenfassung

Diejenigen von Ihnen, die schon länger mit .NET arbeiten, waren womöglich von der integrierten Unterstützung der Konfiguration über „System.Configuration“ enttäuscht. Dies gilt wahrscheinlich insbesondere dann, wenn Sie vom klassischen ASP.NET kommen, bei dem die Konfiguration auf die Dateien „Web.Config“ oder „App.config“ und dann auf den Zugriff auf nur das begrenzt war, was der Knoten „AppSettings“ enthielt. Zum Glück geht die neue Open-Source-API „Microsoft.Extensions.Configuration“ weit über das hinaus, was ursprünglich verfügbar war. Denn es wurden eine Vielzahl neuer Konfigurationsanbieter sowie ein einfach erweiterbares System hinzugefügt, in das Sie beliebige benutzerdefinierte Anbieter integrieren können. Für diejenigen unter Ihnen, die noch in einer Welt vor ASP.NET 5 arbeiten (feststecken?), funktionieren die „System.Configuration“-APIs weiter. Doch Sie können langsam beginnen, zur neuen API zu wechseln (oder diese parallel zu nutzen), indem Sie einfach auf die neuen Pakete verweisen. Darüber hinaus können NuGet-Pakete in Windows-Clientprojekten wie Konsolen- und Windows Presentation Foundation-Anwendungen verwendet werden. Deshalb gibt es, wenn Sie das nächste Mal auf Konfigurationsdaten zugreifen müssen, eigentlich keinen Grund, die „Microsoft.Extensions.Configuration“-API außen vor zu lassen.


Mark Michaelis * ist der Gründer von IntelliTect und arbeitet als leitender technischer Architekt und Trainer. Seit fast zwei Jahrzehnten ist er ein Microsoft MVP und Microsoft-Regionalleiter seit 2007. Michaelis arbeitet in verschiedenen Microsoft-Softwareentwicklungs-Reviewteams mit, einschließlich C#, Microsoft Azure, SharePoint und Visual Studio ALM. Er hält häufig Vorträge bei Entwicklerkonferenzen und hat viele Bücher geschrieben, einschließlich seines letzten „Essential C# 6.0 (5th Edition)“ (itl.tc/­EssentialCSharp). Sie können ihn auf Facebook unter facebook.com/Mark.Michaelis, über seinen Blog unter IntelliTect.com/Mark, auf Twitter: @markmichaelis oder per E-Mail unter mark@IntelliTect.com erreichen.*

Unser Dank gilt den folgenden technischen Experten von IntelliTect für die Durchsicht dieses Artikels: Grant Erickson, Derek Howard, Phil Spokas und Michael Stokesbary