HotAvalonia.Core
3.1.0
Prefix Reserved
dotnet add package HotAvalonia.Core --version 3.1.0
NuGet\Install-Package HotAvalonia.Core -Version 3.1.0
<PackageReference Include="HotAvalonia.Core" Version="3.1.0" />
<PackageVersion Include="HotAvalonia.Core" Version="3.1.0" />
<PackageReference Include="HotAvalonia.Core" />
paket add HotAvalonia.Core --version 3.1.0
#r "nuget: HotAvalonia.Core, 3.1.0"
#:package HotAvalonia.Core@3.1.0
#addin nuget:?package=HotAvalonia.Core&version=3.1.0
#tool nuget:?package=HotAvalonia.Core&version=3.1.0
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
HotAvalonia.Core is a library that provides the core components necessary to enable XAML hot reload for Avalonia apps.
Installation
This library has two shadow dependencies:
Avalonia.Markup.Xaml.Loader(required) - The official Avalonia package responsible for runtime XAML parsing. Note that its version should match the version of the coreAvaloniapackage used by your application for everything to work correctly.MonoMod.RuntimeDetour(optional) - If present,HotAvalonia.Coreuses its capabilities to perform injection-based hot reload, required for it to be able to hot reload embedded assets such as icons and images.
So, to install HotAvalonia.Core, you need to add something like this 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 tailored to your needs:
.FromAssembly(...)- Use this method when you only need to hot reload precompiled XAML contained within a single assembly..FromAppDomain(...)- Use this overload to enable XAML hot reload for all assemblies within anAppDomain..ForAssets(...)-HotAvalonia.Corealso supports hot-reloading assets embedded in the application (e.g., images, icons, etc.). However, theIHotReloadContextinstance returned by this method requires injection-based hot reload to be enabled. Thus,MonoMod.RuntimeDetourmust be available in your app's context.
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 preferredIFileSysteminstance cannot be created.FileSystem.Current- This is the default file system accessor used byHotAvalonia, 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(...)- When developing for mobile platforms, your apps are typically run in an emulator or on a physical device connected to your PC. Even ifHotAvaloniaknows 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 (seeHotAvalonia.Remotefor 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 hot reload config.
AvaloniaHotReloadConfig config = AvaloniaHotReloadConfig.Default with { FileSystem = fileSystem };
// Add path hints if needed.
config.ProjectLocator.AddHint(assembly => assembly.GetName().Name == "MyProject" ? "/home/user/projects/MyProject/src/MyProject" : null);
// Provide your customized config to the hot reload context factories.
IHotReloadContext appDomainContext = AvaloniaHotReloadContext.FromAppDomain(config);
IHotReloadContext assetContext = AvaloniaHotReloadContext.ForAssets(config);
// 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 an input for theXamlCompilerto produce aCompiledXamlDocument.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.,MergeResourceIncludeis replaced withResourceInclude). 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.
Feature Flags
Some features of this library can be toggled via runtime options and environment variables (the latter taking precedence over the former). Note that higher-level libraries such as HotAvalonia provide their own user-friendly wrappers for these features in the form of MSBuild properties, so you will likely want to use those instead of manually setting runtime configuration options.
This section primarily serves to document the raw behavior of HotAvalonia.Core, both for those who may want to build an alternative front end for it and to highlight that you can use environment variables to quickly experiment with the outlined features without recompiling your app or messing with its *.runtimeconfig.json.
Below is the exhaustive list of available runtime options and their default values:
<ItemGroup>
<RuntimeHostConfigurationOption Include="HotAvalonia.InjectionType" Value="MonoMod, CodeCave, PointerSwap" />
<RuntimeHostConfigurationOption Include="HotAvalonia.SkipInitialPatching" Value="false" />
<RuntimeHostConfigurationOption Include="HotAvalonia.MinLogLevel" Value="debug" />
<RuntimeHostConfigurationOption Include="HotAvalonia.Timeout" Value="10000" />
<RuntimeHostConfigurationOption Include="HotAvalonia.Mode" Value="balanced" />
<RuntimeHostConfigurationOption Include="HotAvalonia.Hotkey" Value="Alt+F5" />
<RuntimeHostConfigurationOption Include="HotAvalonia.RemoteFileSystemAddress" Value="" />
<RuntimeHostConfigurationOption Include="HotAvalonia.RemoteFileSystemSecret" Value="" />
<RuntimeHostConfigurationOption Include="HotAvalonia.StaticResourcePatcher" Value="true" />
<RuntimeHostConfigurationOption Include="HotAvalonia.MergeResourceIncludePatcher" Value="true" />
</ItemGroup>
License
Licensed under the terms of the MIT License.
| Product | Versions 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. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.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. |
-
.NETStandard 2.0
- System.Reflection.Emit.Lightweight (>= 4.7.0)
- System.Reflection.Metadata (>= 9.0.3)
-
.NETStandard 2.1
- System.Reflection.Metadata (>= 9.0.3)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on HotAvalonia.Core:
| Package | Downloads |
|---|---|
|
HotAvalonia
An IDE-agnostic hot reload plugin for Avalonia that lets you 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.