共用方式為


使用 MetadataUpdateHandler 擴充 .NET 熱重新載入 (C#、Visual Basic)

您可以使用程式設計方式擴充 .NET 熱重新載入的支援功能,以支援通常不支援的其他案例,例如需要清除快取或重新整理 UI 的程式碼變更。 例如,若要支援 JSON 序列化程式的熱重新載入,您必須在修改類型時清除其快取。 若您是 .NET MAUI 開發人員,可能需要擴充熱重新載入,以便進行一般情況下不會觸發熱重新載入的編輯/更新,例如編輯建構函式或 UI 元素的事件處理常式。 您可以使用 MetadataUpdateHandlerAttribute 重新整理應用程式狀態、觸發 UI 重新轉譯,或執行類似操作。

此屬性指定的類型應該實作與下列一或多項的特徵標記相符的靜態方法:

static void ClearCache(Type[]? updatedTypes)
static void UpdateApplication(Type[]? updatedTypes)

ClearCache 讓更新處理常式有機會清除依據應用程式中繼資料推斷的任何快取。 在叫用所有 ClearCache 方法之後,系統將針對每個指定該方法的處理常式叫用 UpdateApplication。 您可以使用 UpdateApplication 來重新整理 UI。

範例

下列範例示範的 .NET MAUI 專案案例一開始不支援熱重新載入,但在實作 MetadataUpdateHandler 後支援該功能。

測試 .NET 熱重新載入

  1. 在 Visual Studio 中建立新的 .NET MAUI 專案。 選擇 .NET MAUI 應用程式專案範本。

  2. App.xaml.cs 中,將建立 MainPage 的程式碼替換為以下程式碼:

    //MainPage = new MainPage(); // Template default code
    MainPage = new NavigationPage(new MainPage());
    

    接下來,您將實作 Build 方法,以簡化 C# 中的 UI 更新。 這個方法會設定 ContentPage.Content,並在頁面的 OnNavigatedTo 中呼叫。 OnNavigatedTo 事件必須裝載於殼層或 NavigationPage 內。

  3. MainPage.xaml.cs 中,將 MainPage 建構函式程式碼替換為下列程式碼:

    public MainPage()
    {
       InitializeComponent();
       Build();
    }
    
    void Build() => Content =
       new Label
       {
          Text = "First line\nSecond line"
       };
    
    protected override void OnNavigatedTo(NavigatedToEventArgs args)
    {
       base.OnNavigatedTo(args);
       Build();
    }
    
  4. F5 鍵啟動應用程式。

  5. 載入頁面之後,將 C# 程式碼中的標籤文字變更為類似下方所示的內容:「第一行\n第二行\n第三行」

  6. 選取 [熱重新載入] [熱重新載入] 按鈕的螢幕擷取畫面。 按鈕。

    更新後的文字不會在執行中的應用程式顯示。 根據預設,此案例沒有熱重新載入支援功能。

    [熱重新載入] 無法運作的螢幕擷取畫面。

新增 MetadataUpdateHandler

在 .NET MAUI 應用程式中,執行程式碼變更後,您必須執行一些動作,才能重新執行 C# UI 程式碼。 如果 UI 程式碼是以 C# 撰寫,您可以使用MetadataUpdateHandler中的UpdateApplication方法來重新載入 UI。 若要進行這項設定,請使用下列程式碼將 HotReloadService.cs 新增到您的應用程式。

#if DEBUG
[assembly: System.Reflection.Metadata.MetadataUpdateHandlerAttribute(typeof(YourAppNamespace.HotReloadService))]
namespace YourAppNamespace { 
    public static class HotReloadService
    {
        #pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
        public static event Action<Type[]?>? UpdateApplicationEvent;
        #pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

        internal static void ClearCache(Type[]? types) { }
        internal static void UpdateApplication(Type[]? types) {
            UpdateApplicationEvent?.Invoke(types);
        }
    }
}
#endif

請務必將 YourAppNamespace 替換為您目標頁面的命名空間。

新增上述程式碼之後,現在若於 Visual Studio 中編輯即時程式碼,就會發生中繼資料變更,且應用程式會分派 UpdateApplicationEvent。 因此,您必須新增程式碼來註冊事件並執行 UI 更新。

注意

在此案例中,必須啟用 XAML 熱重新載入。

MainPage.xaml.cs 中,新增程式碼以便在OnNavigatedTo事件中註冊UpdateApplicationEvent事件處理常式。

protected override void OnNavigatedTo(NavigatedToEventArgs args)
    {
        base.OnNavigatedTo(args);

        Build();

#if DEBUG
        HotReloadService.UpdateApplicationEvent += ReloadUI;
#endif
    }

取消訂閱 OnNavigatedFrom 中的事件處理常式,然後新增程式碼來處理事件,並重新執行對 Build 的呼叫。

protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
   {
   base.OnNavigatedFrom(args);

#if DEBUG
   HotReloadService.UpdateApplicationEvent -= ReloadUI;
#endif
    }

private void ReloadUI(Type[] obj)
{
   MainThread.BeginInvokeOnMainThread(() =>
   {
      Build();
   });
}

現在,啟動應用程式。 您變更 C# 程式碼中的標籤文字並點擊 [熱重新載入] 按鈕後,UI 即會重新整理!

[熱重新載入] 運作的螢幕擷取畫面。