從 .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
- IAsyncValidateOptions<TOptions>
- IValidateOptions<TOptions>
- AsyncValidateOptions<TOptions>
- AsyncValidateOptions<TOptions,TDep>
- AsyncValidateOptions<TOptions,TDep1,TDep2>
- AsyncValidateOptions<TOptions,TDep1,TDep2,TDep3>
- AsyncValidateOptions<TOptions,TDep1,TDep2,TDep3,TDep4>
- AsyncValidateOptions<TOptions,TDep1,TDep2,TDep3,TDep4,TDep5>
- Value
- CurrentValue
- Get
- Get
- Create
- Create
-
OptionsBuilder<TOptions>上的ValidateAsync擴充方法。