可以通过编程方式扩展 .NET 热重载支持,以实现对通常不支持的其他场景的支持,例如代码更改后需要清除缓存或刷新 UI。 例如,若要支持 JSON 序列化程序的热重载,需要在修改类型时清除其缓存。 对于 .NET MAUI 开发人员,可能需要为在正常条件下不触发热重载(例如编辑构造函数或 UI 元素的事件处理程序)的编辑/更新扩展热重载。 可以使用 MetadataUpdateHandlerAttribute 刷新应用程序状态、触发 UI 重新呈现或执行类似的操作。
此属性指定的类型应实现与以下一个或多个签名匹配的静态方法:
static void ClearCache(Type[]? updatedTypes)
static void UpdateApplication(Type[]? updatedTypes)
ClearCache 使更新处理程序有机会清除基于应用程序的元数据推断的任何缓存。 在调用所有 ClearCache 方法之后,UpdateApplication 会被调用,针对每个指定方法的处理程序。 你可能会使用 UpdateApplication 来刷新 UI。
Example
以下示例演示了最初不支持热重载的 .NET MAUI 项目的场景,但在实现 MetadataUpdateHandler后支持该功能。
测试 .NET 热重载
在 Visual Studio 中创建新的 .NET MAUI 项目。 选择 .NET MAUI 应用 项目模板。
在 App.xaml.cs中,将代码替换为以下代码来创建 MainPage:
//MainPage = new MainPage(); // Template default code MainPage = new NavigationPage(new MainPage());接下来,实现生成方法以简化 C# 中的 UI 更新。 此方法设置
ContentPage.Content并在页面的OnNavigatedTo中调用。 事件OnNavigatedTo必须托管在 Shell 或 NavigationPage 中。在 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(); }按 F5 启动应用。
加载页面后,将 C# 代码中的标签文本更改为“第一行\n第二行\n第三行”
选择 “热重载”按钮

更新后的文本不会显示在正在运行的应用中。 默认情况下,此方案没有热重载支持。
添加 MetadataUpdateHandler
在 .NET MAUI 应用中,在进行代码更改后,必须执行一些作来重新运行 C# UI 代码。 如果 UI 代码是用 C# 编写的,那么可以在 MetadataUpdateHandler 中使用 UpdateApplication 方法来重新加载 UI。 若要设置此设置,请使用以下代码 将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代码。 因此,需要添加代码来注册事件并执行 UI 更新。
注释
对于此方案,必须启用 XAML 热重载。
在MainPage.xaml.cs中,添加代码以在OnNavigatedTo事件中注册UpdateApplicationEvent事件处理程序。
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# 代码中的标签文本并按下“Hot Reload”按钮时,UI 就会刷新!