Leggere la configurazione con stringhe sparse nel codice porta a errori di battitura scoperti solo in produzione. L'Options pattern trasforma una sezione di configurazione in una classe tipizzata e validata.
La classe delle impostazioni
public class SmtpOptions
{
[Required] public string Host { get; set; } = "";
[Range(1, 65535)] public int Port { get; set; } = 587;
[Required, EmailAddress] public string Mittente { get; set; } = "";
}
{
"Smtp": { "Host": "smtp.azienda.it", "Port": 587, "Mittente": "noreply@azienda.it" }
}
Registrazione con validazione all'avvio
builder.Services.AddOptions<SmtpOptions>()
.BindConfiguration("Smtp")
.ValidateDataAnnotations()
.ValidateOnStart();
Con ValidateOnStart l'applicazione non parte se la configurazione è sbagliata: meglio un errore chiaro al deploy che un'email non inviata alle tre di notte.
IOptions, IOptionsSnapshot o IOptionsMonitor?
- IOptions<T>: valori letti una volta, ideale per impostazioni che non cambiano.
- IOptionsSnapshot<T>: ricalcolato a ogni richiesta, utile se il file di configurazione può cambiare a caldo.
- IOptionsMonitor<T>: valore corrente più notifica delle modifiche, adatto ai singleton.
Segreti
Password e chiavi non vanno nel file di configurazione salvato nel repository: in sviluppo si usano gli user secrets, in produzione variabili d'ambiente o un archivio di segreti. L'Options pattern non cambia: legge da tutte queste sorgenti allo stesso modo.
Commenti (0)
Nessun commento ancora.