0Pricing
C# Academy · Lektion

Typsichere Optionen mit IOptions

Binden Sie Konfigurationsabschnitte mithilfe von IOptions , IOptionsSnapshot und IOptionsMonitor an POCO-Klassen.

Typsichere Optionen mit IOptions ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Warum stark typisierte Optionen?

Das Lesen der Konfiguration mit IConfiguration["Key"] liefert untypisierte Zeichenfolgen. Das Options-Pattern ordnet Konfigurationsabschnitte C#-Klassen zu und bietet dadurch Typsicherheit zur Kompilierzeit, IntelliSense und Unterstützung für Validierungen.

Eine Options-Klasse definieren

Erstellen Sie eine einfache POCO-Klasse, deren Eigenschaftsnamen Ihren JSON-Schlüsseln entsprechen. Fügen Sie gemäß Konvention eine statische Konstante namens SectionName hinzu, um den Konfigurationsabschnitt zu identifizieren.

// Configuration class
public class JwtOptions
{
    public const string SectionName = "Jwt";

    public string SecretKey { get; set; } = string.Empty;
    public string Issuer    { get; set; } = string.Empty;
    public string Audience  { get; set; } = string.Empty;
    public int    ExpiryMinutes { get; set; } = 60;
}

// appsettings.json:
{
  "Jwt": {
    "SecretKey": "my-very-secret-key",
    "Issuer": "https://myapp.com",
    "Audience": "https://myapp.com/api",
    "ExpiryMinutes": 120
  }
}

Optionen registrieren

Rufen Sie Configure<T> auf, um einen Konfigurationsabschnitt an die Options-Klasse zu binden. Dadurch werden IOptions<T>, IOptionsSnapshot<T> und IOptionsMonitor<T> in DI registriert.

// Registration
builder.Services.Configure<JwtOptions>(
    builder.Configuration.GetSection(JwtOptions.SectionName));

// Alternative shorthand:
builder.Services
    .AddOptions<JwtOptions>()
    .BindConfiguration(JwtOptions.SectionName);

// Consuming via IOptions<T>:
public class TokenService
{
    private readonly JwtOptions _opts;

    public TokenService(IOptions<JwtOptions> opts)
        => _opts = opts.Value;

    public string CreateToken()
        => $"Issuer={_opts.Issuer}, Exp={_opts.ExpiryMinutes}m";
}

IOptions im Vergleich zu IOptionsSnapshot und IOptionsMonitor

Es gibt drei Varianten mit unterschiedlichen Lebensdauern und unterschiedlichem Verhalten beim Neuladen. Wählen Sie die für Ihren Anwendungsfall passende Variante.

// IOptions<T> — Singleton, reads config ONCE at startup
public class ApiClient(IOptions<ApiOptions> opts)
{
    private readonly ApiOptions _opts = opts.Value; // never changes
}

// IOptionsSnapshot<T> — Scoped, reloads per request
public class ReportService(IOptionsSnapshot<ReportOptions> opts)
{
    private readonly ReportOptions _opts = opts.Value; // fresh per request
}

// IOptionsMonitor<T> — Singleton, live updates + change notifications
public class FeatureService(IOptionsMonitor<FeatureFlags> monitor)
{
    public bool IsEnabled(string feature)
        => monitor.CurrentValue.EnabledFeatures.Contains(feature);
}

Options-Validierung mit Attributen

Versehen Sie die Eigenschaften Ihrer Optionen mit Attributen aus System.ComponentModel.DataAnnotations und rufen Sie ValidateDataAnnotations() auf, damit die Anwendung bei ungültiger Konfiguration sofort beim Start fehlschlägt.

using System.ComponentModel.DataAnnotations;

public class SmtpOptions
{
    [Required]
    public string Host { get; set; } = string.Empty;

    [Range(1, 65535)]
    public int Port { get; set; } = 587;

    [Required, EmailAddress]
    public string FromAddress { get; set; } = string.Empty;
}

// Register with validation:
builder.Services
    .AddOptions<SmtpOptions>()
    .BindConfiguration("Smtp")
    .ValidateDataAnnotations()
    .ValidateOnStart(); // fail at startup, not first use

Benutzerdefinierte Validierung mit IValidateOptions

Für komplexe Regeln zwischen mehreren Eigenschaften implementieren Sie IValidateOptions<T>, um eine vollständig programmgesteuerte Validierungslogik zu erhalten.

public class JwtOptionsValidator : IValidateOptions<JwtOptions>
{
    public ValidateOptionsResult Validate(string? name, JwtOptions opts)
    {
        var errors = new List<string>();

        if (string.IsNullOrWhiteSpace(opts.SecretKey))
            errors.Add("SecretKey must not be empty");

        if (opts.SecretKey.Length < 32)
            errors.Add("SecretKey must be at least 32 characters");

        if (opts.ExpiryMinutes <= 0)
            errors.Add("ExpiryMinutes must be positive");

        return errors.Any()
            ? ValidateOptionsResult.Fail(errors)
            : ValidateOptionsResult.Success;
    }
}

builder.Services.AddSingleton<IValidateOptions<JwtOptions>, JwtOptionsValidator>();

Post-Configure

PostConfigure wird nach allen Aufrufen von Configure ausgeführt und ermöglicht es Ihnen, Werte zu überschreiben oder abzuleiten – nützlich für berechnete Eigenschaften oder umgebungsspezifische Anpassungen.

builder.Services.Configure<CacheOptions>(
    builder.Configuration.GetSection("Cache"));

// Override in test environment:
builder.Services.PostConfigure<CacheOptions>(opts =>
{
    if (builder.Environment.IsEnvironment("Testing"))
    {
        opts.AbsoluteExpirationMinutes = 1; // very short in tests
        opts.UseDistributedCache = false;   // use in-memory cache
    }
});

// PostConfigure always runs LAST, even after AddOptions validators

Benannte Optionen

Wenn Sie mehrere Instanzen desselben Optionstyps benötigen, etwa für zwei SMTP-Server, verwenden Sie benannte Optionen, um sie zu unterscheiden.

// Register named options:
builder.Services.Configure<SmtpOptions>("Primary",
    builder.Configuration.GetSection("Smtp:Primary"));
builder.Services.Configure<SmtpOptions>("Backup",
    builder.Configuration.GetSection("Smtp:Backup"));

// Consume with IOptionsMonitor (supports named options):
public class EmailSender
{
    private readonly SmtpOptions _primary;
    private readonly SmtpOptions _backup;

    public EmailSender(IOptionsMonitor<SmtpOptions> monitor)
    {
        _primary = monitor.Get("Primary");
        _backup  = monitor.Get("Backup");
    }
}

BindConfiguration-Kurzform

Die Kette AddOptions().BindConfiguration() ist die moderne Fluent-Variante, um Registrierung, Bindung, Validierung und sofortiges Fehlschlagen in einem einzigen Ausdruck zu kombinieren.

// Full registration chain:
builder.Services
    .AddOptions<DatabaseOptions>()
    .BindConfiguration("Database")          // bind section
    .ValidateDataAnnotations()               // attribute validation
    .Validate(opts =>                        // custom rule
        opts.MaxPoolSize >= opts.MinPoolSize,
        "MaxPoolSize must be >= MinPoolSize")
    .ValidateOnStart();                      // fail at startup

// Shorthand for simple cases:
builder.Services.AddOptions<AppOptions>()
    .BindConfiguration(AppOptions.SectionName)
    .ValidateOnStart();

Praxisbeispiel: Optionen für Feature Flags

Eine vollständige Konfiguration für Feature-Flag-Optionen mit Unterstützung für das Neuladen, sodass sich Schalter in appsettings ohne erneute Bereitstellung ändern lassen.

public class FeatureFlags
{
    public bool EnableNewCheckout  { get; set; }
    public bool EnableAISearch     { get; set; }
    public bool EnableBetaDashboard { get; set; }
}

// appsettings.json:
// { "FeatureFlags": { "EnableNewCheckout": true, ... } }

builder.Services
    .AddOptions<FeatureFlags>()
    .BindConfiguration("FeatureFlags")
    .ValidateOnStart();

// In a controller or service:
public class CheckoutController : ControllerBase
{
    private readonly FeatureFlags _flags;

    public CheckoutController(IOptionsMonitor<FeatureFlags> m)
        => _flags = m.CurrentValue;

    [HttpGet("/checkout")]
    public IActionResult Index() =>
        _flags.EnableNewCheckout
            ? Ok("new checkout")
            : Ok("legacy checkout");
}

Schnelltest

Welche IOptions-Variante sollten Sie in einem Singleton-Dienst verwenden, der laufende Änderungen an der Konfiguration berücksichtigen muss?

Zusammenfassung: Stark typisierte Optionen mit IOptions

Wichtige Erkenntnisse:

  • Das Options-Pattern bindet Konfigurationsabschnitte über Configure<T> oder AddOptions<T>().BindConfiguration() an POCOs
  • IOptions<T>: Singleton, liest die Werte einmal beim Start
  • IOptionsSnapshot<T>: Scoped, lädt die Werte pro Anfrage neu – nicht in Singletons injizieren
  • IOptionsMonitor<T>: für Singletons geeignet, mit dynamischem CurrentValue + OnChange
  • Validieren Sie mit DataAnnotations + ValidateDataAnnotations() + ValidateOnStart()
  • Benannte Optionen für mehrere Instanzen desselben Typs

Häufig gestellte Fragen

Ist die Lektion „Typsichere Optionen mit IOptions“ kostenlos?

Ja — der vollständige Text von „Typsichere Optionen mit IOptions“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Typsichere Optionen mit IOptions“?

Binden Sie Konfigurationsabschnitte mithilfe von IOptions , IOptionsSnapshot und IOptionsMonitor an POCO-Klassen. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um C# Academy zu starten?

Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Typsichere Optionen mit IOptions“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?

Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Konfigurationsquellen und -anbieter
  2. Typsichere Optionen mit IOptions
  3. Optionsvalidierung und benannte Optionen
  4. Geheimnisverwaltung
← Zurück zu C# Academy