Compartilhar via


Estender o Hot Reload do .NET usando o MetadataUpdateHandler (C#, Visual Basic)

Você pode estender programaticamente o suporte ao .NET Hot Reload para cenários adicionais que normalmente não têm suporte, como alterações de código que exigem limpar um cache ou atualizar a interface do usuário. Por exemplo, para dar suporte ao recarregamento frequente com um serializador JSON, você precisa limpar seu cache quando um tipo é modificado. Para desenvolvedores do .NET MAUI, talvez seja necessário expandir o hot reload para edições/atualizações que normalmente não o disparam, como editar um construtor ou um manipulador de eventos para um elemento da interface do usuário. Você pode usar o MetadataUpdateHandlerAttribute para atualizar o estado do aplicativo, disparar uma renderização da interface do usuário ou executar ações semelhantes.

O tipo especificado por esse atributo deve implementar métodos estáticos que correspondam à assinatura de um ou mais dos seguintes:

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

ClearCache oferece aos manipuladores de atualização a oportunidade de limpar os caches inferidos com base nos metadados do aplicativo. Depois que todos os ClearCache métodos forem invocados, UpdateApplication será invocado para cada manipulador que especifica um. Você pode usar UpdateApplication para atualizar a interface do usuário.

Example

O exemplo a seguir mostra um cenário para um projeto do .NET MAUI que inicialmente não dá suporte ao recarregamento dinâmico, mas dá suporte ao recurso após a implementação MetadataUpdateHandler.

Testar a Recarga Rápida do .NET

  1. Crie um novo projeto MAUI do .NET no Visual Studio. Escolha o modelo de projeto do aplicativo .NET MAUI .

  2. Em App.xaml.cs, substitua o código para criar o MainPage pelo seguinte código:

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

    Em seguida, você implementa um método Build para simplificar uma atualização da interface do usuário em C#. Esse método define o ContentPage.Content e é chamado no OnNavigatedTo da página. O OnNavigatedTo evento deve ser hospedado no Shell ou em uma NavigationPage.

  3. Em MainPage.xaml.cs, substitua o código do MainPage construtor pelo seguinte 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. Pressione F5 para iniciar o aplicativo.

  5. Depois que a página for carregada, altere o texto do rótulo no código C# para algo como: "Primeira linha\nSegunda linha\nTerceira linha"

  6. Selecione o botão Recarga InstantâneaCaptura de tela do botão de Recarga Instantânea.

    O texto atualizado não é exibido no aplicativo em execução. Por padrão, não há suporte ao Hot Reload para esse cenário.

    Captura de tela da Recarga Rápida não funcionando.

Adicionar o MetadataUpdateHandler

Em um aplicativo MAUI do .NET, você deve fazer algo para executar novamente o código da interface do usuário do C# depois de fazer uma alteração de código. Se o seu código de IU for escrito em C#, você poderá usar o método UpdateApplication em MetadataUpdateHandler para recarregar a IU. Para configurar isso, adicione HotReloadService.cs ao aplicativo usando o código a seguir.

#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

Certifique-se de substituir YourAppNamespace pelo namespace da página que você está almejando.

Agora, com o código anterior adicionado, quando você edita o código dinâmico no Visual Studio, ocorre uma alteração de metadados e o aplicativo despacha o UpdateApplicationEvent. Portanto, você precisa adicionar código para registrar o evento e executar a atualização da interface do usuário.

Observação

Para esse cenário, a Recarga Dinâmica do XAML deve estar habilitada.

Em MainPage.xaml.cs, adicione código para registrar o UpdateApplicationEvent manipulador de eventos no OnNavigatedTo evento.

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

        Build();

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

Cancele a assinatura do manipulador de eventos em OnNavigatedFrom e adicione código para tratar o evento e repetir a chamada para Build.

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

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

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

Agora, inicie o aplicativo. Quando você faz uma alteração no texto do rótulo em seu código C# e pressiona o botão Hot Reload, a interface do usuário é atualizada!

Captura de tela do funcionamento do Hot Reload.