2

C# UI and .NET Hot Reload - A Match Made in .NET MAUI

 1 year ago
source link: https://dev.to/davidortinau/c-ui-and-net-hot-reload-a-match-made-in-net-maui-243f
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
David Ortinau

Posted on Oct 10

C# UI and .NET Hot Reload - A Match Made in .NET MAUI

Visual Studio 2022 and .NET 6 introduced .NET Hot Reload, the ability to continue coding C# while debugging your application, and use your changes without stopping. If you've used Edit and Continue, this probably feels similar.

  1. Start debugging your app
  2. Add or edit some C#
  3. Click the "Hot Reload" button in Visual Studio
  4. Re-trigger the code path to exercise your new code

Most of the time in .NET MAUI we (I) use XAML to declare UI, and XAML Hot Reload to avoid repetitive stopping and starting. This can work really well. Anytime you make a XAML edit, as long as the XAML compiler indicates your edit is valid code, the change is shipped to the running app AND the UI is updated while retaining state.

There are many cases when XAML requires me to stop and restart my session, thus breaking my flow. Remaining completely in C# drastically improves this situation.

Marrying C# UI and .NET Hot Reload

When you edit UI code in your C#, you must then do something to run that code again and see the impact of your change. That can become tiresome. Here's what I do.

I like the pattern of placing my UI construction in a Build method. This method sets the ContentPage.Content and is called in the page's OnNavigatedTo method when hosted within Shell or a NavigationPage.

void Build() => Content = 
        new Grid { 

        };

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

    Build();
}

Great! But this method is only going to get called once. I could navigate away from that page and come back. Or I could add a gesture to trigger the method manually. That gets old quickly.

What if I could make sure the Build() method anytime I triggered a hot reload, similar to XAML Hot Reload?

Turns out I can! Anytime .NET Hot Reload executes, a metadata change is triggered, and I can hook into that. To do this, I add a HotReloadService.cs to my project.

#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

Anytime a change happens, the app will now dispatch an event. In the file I'm currently working on, where I want to re-execute the build, I handle the event.

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

        Build();

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

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

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

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

Now give that a try! Make a change to your C# in that page, and hit the Hot Reload fire button (or if you're like me, set hot reload to execute on save). Boom!

XAML Hot Reload must be enabled to leverage this event since it works over the same tooling service. If you disable XAML Hot Reload, then your C# code will reload, but you won't receive the event that you have wired up now to trigger a UI rebuild.

I have found very few scenarios so far when I have to actually stop and restart my debugging session. As you can see in this video, I even add a new class file without stopping.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK