Synchronní přístup k volbám ověřovaným asynchronně vyvolá výjimku

Počínaje verzí .NET 11 RC 1 synchronní přístup k typu options, který používá pouze asynchronní validátory, okamžitě selže. Místo vrácení instance voleb bez asynchronní validace synchronní způsob vytvoření vyvolá OptionsValidationException.

Verze byla představena

.NET 11 RC 1

Předchozí chování

Dříve, v .NET 11 Preview 6 a Preview 7, IAsyncValidateOptions<TOptions> byl nezávislý na IValidateOptions<TOptions>. Asynchronní validátory běžely pouze prostřednictvím cesty asynchronního ověřování při spuštění.

Když jste přistupovali k asynchronně validovanému typu voleb prostřednictvím synchronní cesty vytváření, například IOptions<TOptions>.Value, CurrentValue, Get, IOptionsSnapshot<TOptions>.Value, Get nebo Create, asynchronní validátor se nespustil. Synchronní cesta vrátila neověřenou instanci možností.

Typy, které implementovaly přímo IAsyncValidateOptions<TOptions>, stačilo implementovat pouze ValidateAsync.

Nové chování

Počínaje .NET 11 RC 1 IAsyncValidateOptions<TOptions> je odvozen od IValidateOptions<TOptions>a rozhraní již není kontravariantní. Asynchronní validátory se účastní stejné kolekce validátoru jako synchronní validátory.

Když přistoupíte k typu voleb pouze s asynchronními validátory pomocí synchronní cesty vytvoření, zděděná metoda Validate vrátí neúspěšné ValidateOptionsResult. Create pak vyvolá OptionsValidationException. Zpráva o výjimce vás před synchronním přístupem k možnostem nasměruje na volání ValidateOnStart a dokončení spuštění.

Vlastní typy, které implementují IAsyncValidateOptions<TOptions> přímo, teď také musí implementovat zděděnou Validate metodu.

Typ zásadní změny

Tato změna je změna chování a může ovlivnit kompatibilitu zdroje. V úzkém scénáři, kdy binární soubor ve verzi Preview přímo implementuje IAsyncValidateOptions<TOptions> bez rekompilace, může změna ovlivnit také binární kompatibilitu.

Důvod změny

Ověřování asynchronních možností bylo zavedeno v .NET 11 Preview 6 jako cesta ověřování pouze po spuštění. Pozdější návrhové práce pro validaci po spuštění odhalily nedostatek z hlediska správnosti: Volby mají také synchronní cesty pro vytvoření a přístup. Validátor, který implementoval pouze asynchronní rozhraní, nemohl projít těmito synchronními cestami, takže se před spuštěním asynchronního ověření mohly vrátit neplatné možnosti a uložit je do mezipaměti.

Aby se tato mezera zaplnila dříve, než rozhraní API dosáhne stabilního vydání, IAsyncValidateOptions<TOptions> nyní vychází z IValidateOptions<TOptions>. Sjednocený kontrakt uchovává jednu kolekci validátoru, zachovává pořadí registrace a způsobuje selhání nepodporovaného synchronního přístupu s výjimkou s možností akce. Další informace najdete v tématu dotnet/runtime#131197 a schválený návrh rozhraní API.

Pro možnosti, které používají pouze asynchronní validátory, zavolejte ValidateOnStart a dokončete spuštění hostitele před synchronním přístupem k možnostem:

services.AddOptions<MyOptions>()
    .Configure(o => o.Value = 42)
    .ValidateAsync(o => Task.FromResult(o.Value > 0), "Value must be positive.")
    .ValidateOnStart();

await host.StartAsync();

Vyhněte se synchronnímu přístupu k možnostem, které mají pouze asynchronní validátory, před dokončením spuštění. Tyto pokyny platí pro IOptions<TOptions>.Value, , IOptionsMonitor<TOptions>.GetIOptionsMonitor<TOptions>.CurrentValue, IOptionsSnapshot<TOptions>.Value, IOptionsSnapshot<TOptions>.Get, a IOptionsFactory<TOptions>.Create.

Některé cesty zůstávají synchronní i po použití ValidateOnStart. Ověřování při spuštění nenastavuje výchozí hodnoty IOptionsSnapshot<TOptions> pro pozdější rozsahy a IOptionsMonitor<TOptions> po změně konfigurace synchronně znovu vytváří možnosti. Pokud tyto cesty potřebujete k úspěšnému ověření, ponechte aspoň jeden synchronní validátor.

Pokud implementujete IAsyncValidateOptions<TOptions> přímo, přidejte zděděnou Validate(string? name, TOptions options) metodu a rekompilujte proti .NET 11. Vraťte ValidateOptionsResult.Skip, pokud se validátor neuplatní, nebo vraťte ValidateOptionsResult.Fail, pokud není podporováno synchronní ověření.

Pokud váš kód spoléhal na odstraněnou in TOptions kontravarianci, aktualizujte příslušná přiřazení, přetypování nebo registrace.

Toto chování nemůžete řídit pomocí přepínače Nebo nastavení konfigurace AppContext.

Ovlivněná rozhraní API