Поделиться через


Расширение Горячая перезагрузка .NET с помощью MetadataUpdateHandler (C#, Visual Basic)

Вы можете программно расширить поддержку .NET Горячая перезагрузка для дополнительных сценариев, которые обычно не поддерживаются, например изменения кода, требующие очистки кэша или обновления пользовательского интерфейса. Например, для поддержки горячей перезагрузки с сериализатором JSON необходимо очистить кэш при изменении типа. Разработчикам .NET MAUI может потребоваться расширить горячую перезагрузку для изменений и обновлений, которые не активируют горячую перезагрузку в обычных условиях, например редактирование конструктора или обработчик событий для элемента пользовательского интерфейса. Можно использовать MetadataUpdateHandlerAttribute для обновления состояния приложения, активации повторного отрисовки пользовательского интерфейса или выполнения аналогичных действий.

Тип, указанный этим атрибутом, должен реализовать статические методы, соответствующие сигнатуре одного или нескольких из следующих:

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

ClearCache предоставляет обработчикам обновлений возможность очистить все кэши, которые выводятся на основе метаданных приложения. После вызова всех ClearCache методов вызывается для каждого обработчика, UpdateApplication указывающего один. Вы можете использовать UpdateApplication для обновления пользовательского интерфейса.

Пример

В следующем примере показан сценарий для проекта .NET MAUI, который изначально не поддерживает горячую перезагрузку, но затем поддерживает эту функцию после реализации MetadataUpdateHandler.

Тестирование Горячая перезагрузка .NET

  1. Создайте проект .NET MAUI в Visual Studio. Выберите шаблон проекта приложения .NET MAUI.

  2. В App.xaml.cs замените код на создание MainPage следующим кодом:

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

    Затем вы реализуете метод build для упрощения обновления пользовательского интерфейса в C#. Этот метод задает 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# на следующее: "Первая строка\nSecond line\nThird line"

  6. Нажмите кнопку Горячая перезагрузкаСнимок экрана: кнопка .

    Обновленный текст не отображается в работающем приложении. По умолчанию нет Горячая перезагрузка поддержки этого сценария.

    Снимок экрана: Горячая перезагрузка не работает.

Добавление метаданныхUpdateHandler

В приложении .NET MAUI необходимо выполнить что-то, чтобы повторно запустить код пользовательского интерфейса C# после изменения кода. Если код пользовательского интерфейса написан на C#, можно использовать UpdateApplication метод для MetadataUpdateHandler перезагрузки пользовательского интерфейса. Чтобы настроить это, добавьте 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. Поэтому необходимо добавить код для регистрации события и выполнения обновления пользовательского интерфейса.

Примечание.

Для этого сценария необходимо включить Горячая перезагрузка XAML.

В MainPage.xaml.cs добавьте код для регистрации обработчика UpdateApplicationEvent событий в событии OnNavigatedTo .

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# и нажатии кнопки Горячая перезагрузка пользовательский интерфейс обновляется!

Снимок экрана: Горячая перезагрузка работа.