Erweitern von .NET Hot Reload mithilfe von MetadataUpdateHandler (C#, Visual Basic)

Sie können die Unterstützung von .NET Hot Reload programmgesteuert auf zusätzliche Szenarien erweitern, die in der Regel nicht unterstützt werden, z. B. Codeänderungen, die das Löschen eines Caches oder das Aktualisieren der Benutzeroberfläche erfordern. Um beispielsweise Hot Reload mit einem JSON-Serialisierungsmodul zu unterstützen, müssen Sie den Cache löschen, wenn ein Typ geändert wird. Für .NET MAUI-Entwickler müssen Sie möglicherweise Hot Reload auf Bearbeitungen/Updates erweitern, die unter normalen Bedingungen kein Hot Reload auslösen, z. B. beim Bearbeiten eines Konstruktors oder eines Ereignishandlers für ein Element der Benutzeroberfläche. Sie können MetadataUpdateHandlerAttribute verwenden, um den Anwendungsstatus zu aktualisieren, ein erneutes Rendern der Benutzeroberfläche auszulösen oder ähnliche Aktionen auszuführen.

Der von diesem Attribut angegebene Typ sollte statische Methoden implementieren, die der Signatur einer oder mehrerer der folgenden Methoden entsprechen:

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

ClearCache gibt Updatehandlern die Möglichkeit, alle Caches zu löschen, die basierend auf den Metadaten der Anwendung abgeleitet werden. Nachdem alle ClearCache-Methoden aufgerufen wurden, wird UpdateApplication für jeden Handler aufgerufen, der eine angibt. Sie können UpdateApplication verwenden, um die Benutzeroberfläche zu aktualisieren.

Beispiel

Das folgende Beispiel zeigt ein Szenario für ein .NET MAUI-Projekt, das zunächst Hot Reload nicht unterstützt, aber das Feature nach der Implementierung von MetadataUpdateHandler unterstützt.

Testen von .NET Hot Reload

  1. Erstellen Sie ein neues .NET MAUI-Projekts in Visual Studio. Wählen Sie die Projektvorlage .NET MAUI-App aus.

  2. Ersetzen Sie in App.xaml.cs den Code zum Erstellen der MainPage durch den folgenden Code:

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

    Als Nächstes implementieren Sie eine Build-Methode, um eine Aktualisierung der Benutzeroberfläche in C# zu vereinfachen. Diese Methode legt ContentPage.Content fest und wird in OnNavigatedTo der Seite aufgerufen. Das Ereignis OnNavigatedTo muss in Shell oder einer NavigationPage gehostet werden.

  3. Ersetzen Sie in MainPage.xaml.cs den Konstruktorcode MainPage durch den folgenden Code:

    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. Drücken Sie F5, um die App zu starten.

  5. Ändern Sie nach dem Laden der Seite den Beschriftungstext im C#-Code in Folgendes: „Erste Zeile\nZweite Zeile\nDritte Zeile“

  6. Wählen Sie die Schaltfläche Hot ReloadScreenshot of the Hot Reload button. aus.

    Der aktualisierte Text wird in der ausgeführten App nicht angezeigt. Für dieses Szenario gibt es standardmäßig keine Hot Reload-Unterstützung.

    Screenshot of Hot Reload not working.

Hinzufügen von MetadataUpdateHandler

In einer .NET MAUI-App müssen Sie etwas tun, um C#-Code der Benutzeroberfläche erneut auszuführen, nachdem Sie eine Codeänderung vorgenommen haben. Wenn Ihr Code der Benutzeroberfläche in C# geschrieben ist, können Sie die Methode UpdateApplication in MetadataUpdateHandler verwenden, um die Benutzeroberfläche neu zu laden. Um dies einzurichten, fügen Sie Ihrer Anwendung HotReloadService.cs mit dem folgenden Code hinzu.

#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

Stellen Sie sicher, dass Sie YourAppNamespace durch den Namespace für die gewünschte Seite ersetzen.

Beim Bearbeiten von Livecode in Visual Studio tritt nun nach dem Hinzufügen des vorherigen Codes eine Metadatenänderung auf, und die App sendet UpdateApplicationEvent. Daher müssen Sie Code hinzufügen, um das Ereignis zu registrieren und die Aktualisierung der Benutzeroberfläche durchzuführen.

Hinweis

Für dieses Szenario muss XAML Hot Reload aktiviert sein.

Fügen Sie in MainPage.xaml.cs Code hinzu, um den Ereignishandler UpdateApplicationEvent im Ereignis OnNavigatedTo zu registrieren.

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

        Build();

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

Tragen Sie den Ereignishandler in OnNavigatedFrom aus, und fügen Sie dann Code hinzu, um das Ereignis zu verarbeiten. Führen Sie den Aufruf von Build dann erneut aus.

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

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

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

Starten Sie nun die App. Wenn Sie den Bezeichnungstext in Ihrem C#-Code ändern und auf die Schaltfläche „Hot Reload“ klicken, wird die Benutzeroberfläche aktualisiert!

Screenshot of Hot Reload working.