Extensión de Recarga activa de .NET usando MetadataUpdateHandler (C#, Visual Basic)

Puede ampliar mediante programación la compatibilidad de Recarga activa de .NET con escenarios adicionales que no se admiten normalmente, como los cambios de código que requieren borrar una memoria caché o actualizar la interfaz de usuario. Por ejemplo, para admitir la recarga activa con un serializador JSON, debe borrar su memoria caché cuando se modifica un tipo. En el caso de los desarrolladores de MAUI de .NET, es posible que tenga que ampliar la recarga activa para las ediciones o actualizaciones que no desencadenan la recarga activa en condiciones normales, como editar un constructor o un controlador de eventos para un elemento de la interfaz de usuario. Puede usar MetadataUpdateHandlerAttribute para actualizar el estado de la aplicación, desencadenar una nueva representación de la interfaz de usuario o realizar acciones similares.

El tipo especificado por este atributo debe implementar métodos estáticos que coincidan con la firma de uno o varios de los siguientes:

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

ClearCache proporciona a los controladores de actualizaciones una oportunidad para borrar las memorias caché que se deducen en función de los metadatos de la aplicación. Una vez invocados todos los métodos ClearCache, se invoca UpdateApplication para cada controlador que especifique uno. Puede usar UpdateApplication para actualizar la interfaz de usuario.

Ejemplo

En el ejemplo siguiente se muestra un escenario para un proyecto de .NET MAUI que inicialmente no admite la recarga activa, pero después admite la característica después de implementar MetadataUpdateHandler.

Prueba de Recarga activa de .NET

  1. Creación de un nuevo proyecto de .NET MAUI en Visual Studio. Elija la plantilla de proyecto .NET MAUI App .

  2. En App.xaml.cs, reemplace el código para crear MainPage por el código siguiente:

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

    A continuación, implemente un método de compilación para simplificar la actualización de la interfaz de usuario en C#. Este método establece el ContentPage.Content y se llama en el OnNavigatedTo de la página. El evento OnNavigatedTo debe estar alojado en Shell o en una NavigationPage.

  3. En MainPage.xaml.cs, reemplace el código del constructor MainPage por el siguiente código:

    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. Presione F5 para iniciar la aplicación.

  5. Una vez que se cargue la página, cambie el texto de la etiqueta en el código de C# por algo parecido a: "Primera línea\nSegunda línea\nTercera línea"

  6. Seleccione el botón Recarga activaScreenshot of the Hot Reload button..

    El texto actualizado no se muestra en la aplicación en ejecución. No hay compatibilidad con Recarga activa para este escenario de forma predeterminada.

    Screenshot of Hot Reload not working.

Adición de MetadataUpdateHandler

En una aplicación de .NET MAUI, debe hacer algo para volver a ejecutar el código de interfaz de usuario de C# después de realizar un cambio de código. Si su código de interfaz de usuario está escrito en C#, podría usar el método UpdateApplication en MetadataUpdateHandler para recargar la interfaz de usuario. Para configurarlo, agregue HotReloadService.cs a la aplicación mediante el código siguiente.

#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

Asegúrese de reemplazar YourAppNamespace por el espacio de nombres de la página de destino.

Ahora, con el código anterior agregado, al editar código activo en Visual Studio, se produce un cambio de metadatos y la aplicación envía el UpdateApplicationEvent. Por lo tanto, debe agregar código para registrar el evento y realizar la actualización de la interfaz de usuario.

Nota

En este escenario, Recarga activa de XAML debe estar habilitado.

En MainPage.xaml.cs, agregue código para registrar el controlador de eventos UpdateApplicationEvent en el evento OnNavigatedTo.

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

        Build();

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

Anule la suscripción del controlador de eventos en OnNavigatedFrom y después agregue código para controlar el evento y vuelva a ejecutar la llamada a Build.

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

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

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

Ahora, inicie la aplicación. Cuando realice un cambio en el texto de la etiqueta en el código de C# y presione el botón Recarga activa, la interfaz de usuario se actualiza.

Screenshot of Hot Reload working.