Partilhar via


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

Você pode estender programaticamente o suporte ao .NET Hot Reload para cenários adicionais que normalmente não são suportados, como alterações de código que exigem a limpeza de um cache ou a atualização da interface do usuário. Por exemplo, para dar suporte à recarga a quente com um serializador JSON, você precisa limpar seu cache quando um tipo é modificado. Para desenvolvedores do .NET MAUI, talvez seja necessário estender o hot reload para edições/atualizações que não acionam o hot reload em condições normais, 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 nova renderização da interface do usuário ou executar ações semelhantes.

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

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

ClearCache Dá aos manipuladores de atualização a oportunidade de limpar todos os caches inferidos com base nos metadados do aplicativo. Depois que todos os ClearCache métodos tiverem sido invocados, UpdateApplication é 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 .NET MAUI que inicialmente não oferece suporte a hot reload, mas depois oferece suporte ao recurso após a implementação MetadataUpdateHandler.

Teste o .NET Hot Reload

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

  2. No App.xaml.cs, substitua o código para criar a MainPage com o 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#. Este método configura o ContentPage.Content e é chamado na OnNavigatedTo da página. O OnNavigatedTo evento deve ser hospedado no Shell ou em uma NavigationPage.

  3. No 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 Hot ReloadCaptura de ecrã do botão Hot Reload.

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

    Captura de ecrã do Hot Reload a não funcionar.

Adicionar o manipulador de atualização de metadados

Em um aplicativo .NET MAUI, você deve fazer algo para executar novamente o código da interface do usuário C# depois de fazer uma alteração de código. Se o código da interface do utilizador estiver escrito em C#, pode utilizar o método UpdateApplication em MetadataUpdateHandler para recarregar a interface do utilizador. Para configurar isso, adicione HotReloadService.cs ao seu 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á segmentando.

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 envia o UpdateApplicationEvent. Então, 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, o XAML Hot Reload deve ser habilitado.

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

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

        Build();

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

Desinscreva o manipulador de eventos em OnNavigatedFrom e, em seguida, adicione código para manipular o evento e execute novamente 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 ecrã de Hot Reload a funcionar.