同步存取非同步驗證選項的拋出

從 .NET 11 RC 1 開始,對僅使用非同步驗證器的選項類型進行同步存取會很快失敗。 同步建立路徑不會回傳未經非同步驗證的選項執行個體,而是拋出 OptionsValidationException。

所推出的版本

.NET 11 RC 1

以前的行為

先前在 .NET 11 預覽版 6 和預覽版 7 中,IAsyncValidateOptions<TOptions>獨立於 IValidateOptions<TOptions>。 非同步驗證器僅透過非同步啟動驗證路徑執行。

當你透過同步建立路徑(如 IOptions<TOptions>.Value、 CurrentValue、 GetIOptionsSnapshot<TOptions>.Value、 Get、 或Create)存取非同步驗證的選項類型時,非同步驗證器並未執行。 同步路徑回傳一個未驗證的選項實例。

直接實作 IAsyncValidateOptions<TOptions> 的類型只需實作 ValidateAsync。

新行為

從 .NET 11 開始, IAsyncValidateOptions<TOptions> RC 1 源自 IValidateOptions<TOptions>,介面不再是逆變的。 非同步驗證器與同步驗證器共用同一個驗證器集合。

當你透過同步建立路徑存取僅具有非同步驗證器的選項類型時,繼承的 Validate 方法會回傳失敗的 ValidateOptionsResult。 Create 接著拋出一個 OptionsValidationException。 例外訊息會指示你先打電話 ValidateOnStart 並完成啟動,然後才能同步進入選項。

直接實作 IAsyncValidateOptions<TOptions> 的自訂型態現在也必須實作繼 Validate 承的方法。

破壞性變更的類型

此變更是 行為變更 ,可能會影響 來源相容性。 在預覽二進位檔直接實作 IAsyncValidateOptions<TOptions> 且不需重新編譯的狹窄情境中,變更也可能影響 二進位相容性。

變更原因

非同步選項驗證於 .NET 11 預覽版 6 中引入,作為僅限啟動時的驗證路徑。 後續啟動驗證的設計工作揭示了正確性缺口:選項同時具備同步建立與存取路徑。 僅實作非同步介面的驗證器無法通過這些同步路徑,因此無效選項可能會被回傳並快取,然後才進行非同步驗證。

為了在 API 達到穩定版本前填補這個差距, IAsyncValidateOptions<TOptions> 現在 是從 衍生出來 IValidateOptions<TOptions>的。 統一合約保留一個驗證者集合,保留註冊順序,並使不支援的同步存取失敗,並附設可操作的例外。 更多資訊請參閱 dotnet/runtime#131197 及 已核准的 API 提案。

對於僅使用非同步驗證器的選項,請先呼叫 ValidateOnStart 並完成主機啟動,再同步存取選項:

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

await host.StartAsync();

在啟動完成之前,避免同步存取僅含非同步驗證器的選項。 此指引適用於 IOptions<TOptions>.Value、 IOptionsMonitor<TOptions>.CurrentValue、 IOptionsMonitor<TOptions>.Get、 IOptionsSnapshot<TOptions>.ValueIOptionsSnapshot<TOptions>.GetIOptionsFactory<TOptions>.Create、 及 。

即使使用 ValidateOnStart了 ,有些路徑仍保持同步。 啟動驗證不會為後續範圍預先植入 IOptionsSnapshot<TOptions> 值,而 IOptionsMonitor<TOptions> 會在設定變更後同步重新建立選項。 如果你需要這些路徑才能成功驗證,至少要保留一個同步驗證器。

如果你直接實作 IAsyncValidateOptions<TOptions>,請加入繼承而來的 Validate(string? name, TOptions options) 方法,並針對 .NET 11 重新編譯。 當驗證者不適用時回傳 ValidateOptionsResult.Skip ,或在不支援同步驗證時回傳 ValidateOptionsResult.Fail 。

如果您的程式碼依賴已移除的 in TOptions 逆變,請更新受影響的指派、型別轉換或註冊。

你無法用 AppContext 開關或設定來控制這種行為。

受影響的 API