C# Academy · leksjon

Sterkt typede alternativer med IOptions

Bind konfigurasjonsseksjoner til POCO-klasser med IOptions , IOptionsSnapshot og IOptionsMonitor .

Leksjon 2 av 412 trinn

Sterkt typede alternativer med IOptions er en gratis leksjon i C# Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i C# Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i C# Academy inneholder totalt 4 leksjoner.

Hvorfor bruke sterkt typede options?

Hvis konfigurasjon leses med IConfiguration["Key"], får De utypede strenger. Options-mønsteret kobler konfigurasjonsseksjoner til C#-klasser og gir typesikkerhet ved kompilering, IntelliSense og støtte for validering.

Definere en options-klasse

Opprett en vanlig POCO-klasse der egenskapsnavnene samsvarer med JSON-nøklene. Etter konvensjonen bør De legge til en statisk SectionName-konstant for å identifisere konfigurasjonsseksjonen.

// 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
  }
}

Registrere options

Kall Configure<T> for å koble en konfigurasjonsseksjon til options-klassen. Dette registrerer IOptions<T>, IOptionsSnapshot<T> og IOptionsMonitor<T> i DI.

// 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 kontra IOptionsSnapshot kontra IOptionsMonitor

Det finnes tre varianter med ulike levetider og ulik oppførsel ved omlasting. Velg den som passer bruksområdet.

// 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);
}

Validering av options med attributter

Utstyr options-egenskaper med attributter fra System.ComponentModel.DataAnnotations, og kall ValidateDataAnnotations() for å stoppe umiddelbart under oppstart hvis konfigurasjonen er ugyldig.

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

Egendefinert validering med IValidateOptions

For komplekse regler på tvers av egenskaper implementerer De IValidateOptions<T> for full programmatisk valideringslogikk.

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 kjøres etter alle kall til Configure og lar Dem overstyre eller utlede verdier – nyttig for beregnede egenskaper eller miljøspesifikke justeringer.

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

Navngitte options

Når De trenger flere instanser av samme options-type, for eksempel to SMTP-servere, kan De bruke navngitte options for å skille dem fra hverandre.

// 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");
    }
}

Kortform med BindConfiguration

Kjeden AddOptions().BindConfiguration() er den moderne, flytende måten å registrere, koble til, validere og stoppe umiddelbart på – alt i ett uttrykk.

// 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();

I praksis: Options for feature-flagg

Et komplett oppsett av options for feature-flagg med støtte for omlasting, slik at brytere kan endres i appsettings uten ny distribusjon.

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");
}

Hurtigsjekk

Hvilken IOptions-variant bør De bruke i en Singleton-tjeneste som skal gjenspeile løpende endringer i konfigurasjonen?

Oppsummering: Sterkt typede options med IOptions

Viktigste punkter:

  • Options-mønsteret kobler konfigurasjonsseksjoner til POCO-er via Configure<T> eller AddOptions<T>().BindConfiguration()
  • IOptions<T>: Singleton, leses én gang ved oppstart
  • IOptionsSnapshot<T>: Scoped, lastes inn på nytt per forespørsel – skal ikke injiseres i Singletons
  • IOptionsMonitor<T>: trygg å bruke i Singletons, med løpende CurrentValue + OnChange
  • Valider med DataAnnotations + ValidateDataAnnotations() + ValidateOnStart()
  • Navngitte options for flere instanser av samme type
Gratis å komme i gang

Lær deg C# med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
93
Leksjoner
346

Ofte stilte spørsmål

Er leksjonen «Sterkt typede alternativer med IOptions» gratis?

Ja – hele teksten i «Sterkt typede alternativer med IOptions» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av C# Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i C# Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Sterkt typede alternativer med IOptions»?

Bind konfigurasjonsseksjoner til POCO-klasser med IOptions , IOptionsSnapshot og IOptionsMonitor . Du øver på C# Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med C# Academy?

Ingen tidligere erfaring er nødvendig. C# Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Sterkt typede alternativer med IOptions»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne C# Academy-leksjonen?

Ja. Alle C# Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Konfigurasjonskilder og leverandører
  2. Sterkt typede alternativer med IOptions
  3. Validering av alternativer og navngitte alternativer
  4. Håndtering av hemmeligheter
← Tilbake til C# Academy