元件可以在共用組件中編譯,但仍可能無法在其中一個呈現它的應用程式中建構。
當瀏覽器與 .NET MAUI 主機重用相同的 Blazor 頁面時,這很容易被忽略。此功能看起來只存在一次,但每個主機仍擁有自己的相依性注入容器、啟動路徑以及生命週期模型。
最近提交的一項修正讓這個問題變得具體。一個共用頁面新增了一個必要的工作流程相依性。原生主機已在它們共同的啟動路徑中註冊它。瀏覽器主機則透過另一個組合根呈現相同的頁面,而該相依性在此處未知。頁面在能夠呈現之前就失敗了。
持久的教訓並非「記住多一個註冊」,而是共用 UI 會為每個能夠呈現它的主機建立一份合約。
共用組件並不代表共用容器
編譯時期重用問的是多個專案是否能參考某個元件。執行時期組合問的是每個主機是否能建構它並滿足所需的行為。
原生主機可能呼叫包裝器啟動,而瀏覽器主機則呼叫面向 Web 的啟動路徑。兩者載入相同的 Razor 元件,卻不建立相同的服務圖。
這產生了一個有用的審查規則:
共用元件上的必要注入,就是每個能呈現它的組合根上的必要合約。
主機清單很重要。「所有原生應用程式都使用此啟動」是不夠的,如果瀏覽器、桌面、測試或預覽主機是透過另一條路徑呈現該頁面。
不要用選擇性來修補遺失的主機功能
當某個主機無法提供相依性時,使其可為 null 可能感覺很務實。這對像是觸覺回饋這類選擇性增強是合理的。但當該相依性強制執行工作流程不變量時,這是危險的。
在被審查的變更中,工作流程必須知道執行時期內容在操作進行中是否保持相同。原生應用程式可以在執行時期變更該內容。瀏覽器主機則不能;它的內容在應用程式生命週期中是固定的。
選擇性會將「此主機以不同的方式呈現穩定性」轉變為「此主機可能略過安全檢查」。這兩者並不相等。
更好的問題是:工作流程真正需要的最小功能是什麼?
它只需要三個事實:
- 識別目前內容的修訂;
- 內容是否已準備好進行工作;
- 內容已變更的訊號。
它不需要原生主機的完整導航、儲存或 UI 服務。一旦較小的合約明確,兩個主機都能說出真相。
固定與即時配接器可以滿足同一不變量
瀏覽器實作可以是固定的:
- 它的修訂永不變更;
- 它在應用程式啟動後即準備好;
- 它的變更訊號永不觸發。
原生實作可以是即時的:
- 它的修訂來自執行時期內容;
- 準備狀態反映選擇是否存在;
- 它的訊號遵循真正的內容變更。
它們行為不同,卻保留相同的承諾:在某個內容中開始的工作不得在該內容變更後靜默提交。抽象命名了每個平台都能遵守的最小不變量,而非消除平台差異。
在主機實際進入的地方註冊合約
原本的註冊位於原生應用程式共用的啟動中。它看起來很中心,因為多個主機呼叫它,但它並非每個呈現該頁面的主機的中心。
修正將共用工作流程合約移到兩個實際的組合路徑:
- 瀏覽器路徑註冊固定配接器;
- 原生路徑註冊即時配接器;
- 兩者都註冊必要的共用工作流程;
- 原生專用包裝器不再是意外的授權者。
重複的註冊記錄了一個真實的分裂:相同的工作流程,不同的主機真相。共同註冊仍適合相同的服務;主機特定的配接器應留在主機選擇它們的地方可見。
測試行為與組合
註冊測試很有用,因為這個失敗發生在元件行為開始之前。
一個聚焦的矩陣可以涵蓋:
- 瀏覽器組合根包含共用工作流程與固定配接器;
- 原生組合根包含共用工作流程與即時配接器;
- 舊的平台專用啟動不是隱藏的第三個授權者;
- 當主機有真正固定的內容時,工作流程成功;
- 當即時內容在操作中途變更時,工作流程拒絕或修復完成。
描述元檢查可以快速捕捉遺失的註冊。行為測試證明配接器保留了不變量。兩者都不會啟動完整的實際主機。對於高價值頁面,請加入煙霧測試,建置每個主機的真實提供者並建構頁面邊界;這可以暴露描述元檢查遺漏的生命週期或替換錯誤。
權衡
窄合約方法需要付出一個介面、兩個配接器、明確的註冊,以及更寬的測試矩陣。
替代方案只在局部較便宜:
- 寬泛的原生服務會將平台關切洩漏到共用工作流程程式碼中;
- 選擇性相依性可能靜默停用安全不變量;
- 一個過大的啟動會隱藏哪個主機擁有哪個行為;
- 臨時檢查會在沒有命名合約的情況下漂移。
我偏好在組合邊界進行小而有意的重複,而不是在工作流程內隱含行為差異。
實用審查清單
當共用 Blazor 元件新增必要相依性時,請問:
- 哪些瀏覽器、原生、桌面、測試和預覽主機可以呈現它?
- 每個主機是透過哪個組合根進入?
- 該相依性是工作流程需要的功能,還是它碰巧接收的大型平台服務?
- 每個主機是否都能提供真實、非選擇性的實作?
- 主機差異是否在配接器中可見,而非在 null 分支中?
- 測試是否針對每個根執行註冊與行為?
- 完整的提供者煙霧測試是否能捕捉生命週期或替換錯誤?
共用 UI 並非共用執行時期拓樸的證據。將每個必要相依性視為跨主機的設計決策,而組合根就成為元件真實 API 的一部分。
在您的系統中,哪個共用頁面正在悄悄假設它只有一個主機?
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.