Konfiguration von .NET 5.0-Anwendungen

In diesem Artikel soll beschrieben werden, wie .NET Core Anwendungen konfiguriert werden können. Die Einstellungen können aus JSON-Dateien, Umgebungsvariablen,… bezogen werden. Diese Konfigurationsquellen werden vorallem bei Microservices oder Serveranwendungen genutzt.

Minimalistisches Beispiel

Im nachfolgenden Beispiel wird eine Konsolenanwendung realisiert, die mittels dem ConfigurationBuilder eine Konfiguration selbstständig erstellt und verwendet.

Optionspattern

Um verschiedene Einstellungen zu ordnen wird das Optionspattern genutzt. Dadurch erhalten z.B. verschiedene Anwendungsbereiche nur die für sie relevanten Optionen. Im Folgenden ist eine Beispiel Optionsklasse gezeigt. Das Feld Title bestimmt den Konsolentitel der Anwendung.

public class ConsoleOptions
{
	public string Title { get; set; }
}

Abhängigkeiten

Zunächst müssen folgende NuGet-Pakete, z.B. mit dem Package-Manager oder der .NET CLI eingebunden werden:

PM> Install-Package Microsoft.Extensions.Configuration
PM> Install-Package Microsoft.Extensions.Configuration.Binder
PM> Install-Package Microsoft.Extensions.Configuration.Json

Mit dem Binder-Package kann die Konfiguration als Optionsklasse zur Verfügung gestellt werden. Das JSON-Paket ist ein Konfigurations-Provider, der die Konfiguration aus dem JSON-Format ausliest. Es stehen weitere Provider für INI-Dateien, Kommandozeilenparameter,… zur Verfügung.

Erstellen der Konfiguration

Mit dem ConfigurationBuilder kann die Konfiguration erstellt werden. Die Methode Build gibt anschließend die Konfiguration vom Typ IConfiguration zurück. GetSection gibt die IConfigurationSection mit dem angegebenen Key (hier der Name der Klasse) zurück. Die generische Get-Methode bindet die Konfiguration an ein ConsoleOptions-Objekt. Das erzeugte ConsoleOptions-Objekt kann dann z.B. mittels Dependency Injection an eine Klasse, welche die Optionen benötigt, weitergegeben werden. Um weitere Einstellungen zu verwalten können neue Optionsklassen definiert und aus der jeweiligen Sektion ausgelesen werden.

IConfiguration config = new ConfigurationBuilder()
	.AddJsonFile("test.json")
	.Build();
ConsoleOptions consoleOptions = config.GetSection(nameof(ConsoleOptions)).Get<ConsoleOptions>();

// Setze Konsolentitel:
Console.Title = consoleOptions.Title;

Inhalt der test.json:

{
    "ConsoleOptions": {
        "Title": "OBG IT Solutions GmbH"
    }
}

Konfiguration mit .NET-Hosts

Mit einem generischen Host-Objekt wird einer Anwendung Konfiguration, Dependency Injection, Logging,… zur Verfügung gestellt. Dienste (Ableitungen von IHostedService) können im Host registriert werden. Diese Dienste werden beim Start des Hostes aufgerufen. Diese Technik ist vorallem aus ASP.NET Core bekannt, bei der Serverimplementierungen als Dienste hinzugefügt werden können. Hosts lassen sich aber auch z.B. in Konsolenanwendungen nutzen:

Das folgende Beispiel erstellt einen Host und fügt eine Konfiguration in ConfigureHostConfiguration hinzu (wie oben). Um vergleichbar mit dem Beispiel von oben zu sein, wurde die Standard-Konfiguration nicht genutzt. Mit Configure werden die Konfigurationsdienste hinzugefügt. Hier wird wie oben, die Sektion ConsoleOptions aus der Konfiguration ausgelesen. Als Beispiel wurde ein einfacher Service (MyService) hinzugefügt, der die Konfiguration konsumieren soll. Für jeden Dienst oder Programmabschnitt kann dadurch ohne Umstände eine eigene Konfigurationssektion und Optionsklasse zur Verfügung gestellt werden.

    class Program
    {
        static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) => 
            Host.CreateDefaultBuilder(args)
            .ConfigureHostConfiguration(configHost =>
            
            {
                configHost.SetBasePath(System.IO.Directory.GetCurrentDirectory());
                configHost.AddJsonFile("test.json");
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<MyService>();
                services.Configure<ConsoleOptions>(hostContext.Configuration.GetSection(nameof(ConsoleOptions)));
            });
    }

Der Beispiel-Service MyService kann die Konfiguration dann per Konstruktor Injektion entgegennehmen. Das initalisierte IOptions-Objekt verfügt in der Eigenschaft Value über die konfigurierte Instanz vom Typ ConsoleOptions.

public class MyService : IHostedService
{
    private readonly ConsoleOptions _options;
    public MyService(IOptions<ConsoleOptions> options)
    {
        _options = options.Value;
    }
//...
}