HotAvalonia.Core 3.0.0

Prefix Reserved
dotnet add package HotAvalonia.Core --version 3.0.0
                    
NuGet\Install-Package HotAvalonia.Core -Version 3.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="HotAvalonia.Core" Version="3.0.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="HotAvalonia.Core" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="HotAvalonia.Core">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add HotAvalonia.Core --version 3.0.0
                    
#r "nuget: HotAvalonia.Core, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=HotAvalonia.Core&version=3.0.0
                    
Install HotAvalonia.Core as a Cake Addin
#tool nuget:?package=HotAvalonia.Core&version=3.0.0
                    
Install HotAvalonia.Core as a Cake Tool

[!IMPORTANT]

You probably don't want to install this package manually. Please, check out the main HotAvalonia package, which will set everything up for you automatically.

HotAvalonia.Core

GitHub Build Status Version License

HotAvalonia.Core is a library that provides the core components necessary to enable XAML hot reload for Avalonia apps.


Installation

This library is a bit tricky to set up, because it has two shadow dependencies:

  • Avalonia.Markup.Xaml.Loader (required) - The official Avalonia package responsible for runtime XAML parsing. Note that its version must match the version of the core Avalonia package used by your application for everything to work properly.
  • MonoMod.RuntimeDetour (optional) - If present, HotAvalonia uses its capabilities to perform injection-based hot reload.

To install HotAvalonia.Core, run the following commands:

dotnet add package HotAvalonia.Core
dotnet add package Avalonia.Markup.Xaml.Loader
# optional: dotnet add package MonoMod.RuntimeDetour

Alternatively, you can manually add these PackageReference entries to your project file:

<PackageReference Include="HotAvalonia.Core" Version="..." PrivateAssets="All" />
<PackageReference Include="Avalonia.Markup.Xaml.Loader" Version="..." PrivateAssets="All" />




Usage

AvaloniaHotReloadContext

AvaloniaHotReloadContext provides a simple way to create a hot reload context based on your needs:

  • .FromAssembly(...) / .FromControl(...) - If you only need to hot reload precompiled XAML contained within a single assembly, use one of these methods.
  • .FromAppDomain(...) - If you need to enable XAML hot reload for all assemblies (past, present, and future) within a given AppDomain, consider this overload.
  • .ForAssets(...) - HotAvalonia also supports hot-reloading assets embedded in the application (e.g., images, icons, etc.). However, the IHotReloadContext instance returned by this method requires injection-based hot reload to be enabled. Thus, MonoMod.RuntimeDetour must be available in your app's context, and the HOTAVALONIA_DISABLE_INJECTIONS environment variable should not be set to 1 or true.

So, to enable full hot reload for your app, you might do something like this:

// Don't forget to store your hot reload context somewhere, so it doesn't get GCed out of existence!
_context = AvaloniaHotReloadContext.FromAppDomain().Combine(AvaloniaHotReloadContext.ForAssets());
_context.EnableHotReload();

AvaloniaProjectLocator

For HotAvalonia to work, it must know where the source code for the project that produced a given control assembly is located. Usually, it can deduce this information from the corresponding .pdb file. However, if the .pdb is unavailable, the project is located on a remote device (more on that later), or it's in a different location than indicated by the .pdb, you can tweak the project path resolution logic using this class and one of its .AddHint(...) overloads:

AvaloniaProjectLocator locator = new AvaloniaProjectLocator();

// If you have a materialized `Assembly` object, prefer this overload over other ones:
locator.AddHint(typeof(MyControl).Assembly, "/home/user/projects/MyProject/src/MyProject");

// If you don't have an `Assembly` instance (for example, if it has not been loaded yet),
// but you do know its name (the one returned by `assembly.GetName().Name`), you can use
// it instead:
locator.AddHint("MyProject", "/home/user/projects/MyProject/src/MyProject");

// For full control over the project path resolution logic, use the overload that accepts a `Func<Assembly, string?>`.
// If you recognize the assembly passed to your callback, return the path to its source project location.
// Otherwise, return `null` and let HotAvalonia handle it.
locator.AddHint(assembly => assembly.GetName()?.Name == "MyProject" ? "/home/user/projects/MyProject/src/MyProject" : null);

Please note that HotAvalonia requires a path to the root of the project (i.e., where your .*proj file is located) that was compiled into the provided assembly, not the location of the assembly itself. So, it is not as simple as assembly => assembly.Location!

FileSystem

You can supply HotAvalonia with a custom file system accessor in case you scenario requires one. Here are some common options:

  • FileSystem.Empty - Does exactly as advertised, i.e., absolutely nothing. Although you typically wouldn't use this one if you want a working hot reload, it works well as a fallback when your preferred IFileSystem instance cannot be created.
  • FileSystem.Current - This is the default file system accessor used by HotAvalonia, as the source files for your projects are usually located on the same machine where you debug your app (at least when we talk about desktop development).
  • FileSystem.Connect(...) / FileSystem.ConnectAsync(...) - When developing for mobile platforms, your apps are typically run in an emulator or on a physical device connected to your PC (unless you're a psychopath who develops Android apps directly on an Android device; if that's the case, please seek professional help). Even if HotAvalonia knows the paths of the source projects on your development machine, these paths are inaccessible from the device where the app is being executed. To solve this problem, you can start a simple read-only file system server on your development machine (see HotAvalonia.Remote for more details) and then connect to that server from within your app using one of the mentioned overloads.

Now it's time to bring everything we've learnt so far together - here's how you can provide a custom file system accessor to a hot reload context:

// Connect to a file system server.
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.0.42"), 20158);
byte[] secret = Encoding.UTF8.GetBytes("My Super Secret Value");
IFileSystem fileSystem = FileSystem.Connect(endpoint, secret, fallbackFileSystem: FileSystem.Empty);

// Create a project locator using that file system accessor, and add path hints if needed.
AvaloniaProjectLocator locator = new AvaloniaProjectLocator(fileSystem);
locator.AddHint(assembly => assembly.GetName()?.Name == "MyProject" ? "/home/user/projects/MyProject/src/MyProject" : null);

// Provide your customized project locator to the hot reload context factories.
IHotReloadContext appDomainContext = AvaloniaHotReloadContext.FromAppDomain(AppDomain.Current, locator);
IHotReloadContext assetContext = AvaloniaHotReloadContext.ForAssets(AvaloniaServiceProvider.Current, locator);

// Finally, enable your combined hot reload context.
_context = appDomainContext.Combine(assetContext);
_context.EnableHotReload();

HotAvalonia.Xaml

If you need or want to dig deeper, you might be interested in the HotAvalonia.Xaml namespace, which contains some of the most important primitives powering the underlying XAML hot reload mechanism. Here's a pretty basic overview of those:

  • XamlDocument - Serves as input for the XamlCompiler to produce a CompiledXamlDocument.
  • CompiledXamlDocument - Contains all the relevant information about a control compiled from a XAML document, including its URI and the type of its root element. It also provides methods to build a new control instance defined by the document from scratch, or to (re)populate an existing one.
  • XamlCompiler - Compiles the XAML documents you supply it with.
  • XamlScanner - Offers several utility methods to assist with processing XAML documents precompiled by Avalonia. For example, you can use this class to extract all Avalonia controls from a given assembly.
  • XamlPatcher - Some features of Avalonia (e.g., MergeResourceInclude) are designed to optimize your app's production build performance by inlining external documents into the current one. This allows you to enjoy the best of both worlds: code separation and decent performance, as you no longer need to instantiate 100 different resource dictionaries at runtime just to include them in a single control once. However, this approach makes hot reload somewhat tricky for components referenced in this way, as their source XAML is effectively inlined into another document. As a result, changes to them do not directly affect the app. To see the updates, you would need to hot reload the document into which they were inlined - an unintuitive (and to be quite frankly honest with you, just annoying) experience for end users. To address this, XAML patchers have been introduced into the codebase. These patchers replace inlinable declarations with their less efficient but semantically identical counterparts (e.g., MergeResourceInclude is replaced with ResourceInclude). At the end of the day, this is a debug build we're talking about, so efficiency isn't a priority here, but a good development experience is.

Environment Variables

Some features of this library can be toggled via environment variables:

Name Description Default Examples
HOTAVALONIA_DISABLE_INJECTIONS Forces HotAvalonia to ignore MonoMod.RuntimeDetour, if present, thereby disabling injection-based hot reload. false true <br> false <br> 1 <br> 0
HOTAVALONIA_LOG_LEVEL_OVERRIDE Overrides HotAvalonia's base log level, promoting all logs to a higher severity. For example, setting it to error will make even debug logs appear as errors. N/A information <br> warning <br> error
HOTAVALONIA_SKIP_INITIAL_PATCHING Hot reload contexts created by this library automatically patch and reload all controls that need patching upon being enabled. If this behavior causes issues for you, you can disable it using this variable. false true <br> false <br> 1 <br> 0
HOTAVALONIA_STATICRESOURCEPATCHER Enables the XAML patcher that replaces 'StaticResource' declarations with 'DynamicResource' ones. true true <br> false <br> 1 <br> 0
HOTAVALONIA_MERGERESOURCEINCLUDEPATCHER Enables the XAML patcher that replaces MergeResourceInclude declarations with ResourceInclude ones. true true <br> false <br> 1 <br> 0

License

Licensed under the terms of the MIT License.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on HotAvalonia.Core:

Package Downloads
HotAvalonia

A hot reload plugin for Avalonia that enables you to see UI changes in real time as you edit XAML files, drastically accelerating your design and development workflow.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.0 385 3/23/2025