AOT Compatibility
Crystal.Avalonia is fully compatible with .NET AOT (Ahead-of-Time) compilation and trimming.
What is AOT?
AOT compilation converts your .NET code to native code at build time, rather than at runtime via JIT compilation. This results in:
- Faster startup time
- Reduced memory footprint
- Smaller deployment size (with trimming)
- No JIT overhead
Crystal.Avalonia AOT Features
IsAotCompatible
The library is marked as AOT-compatible:
<PropertyGroup>
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>
DynamicallyAccessedMembers Annotations
All generic methods that use reflection (like Activator.CreateInstance) are properly annotated:
public static void AddMvvmTransient<
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>
(this IServiceCollection services)
where TView : Control where TViewModel : class
{
// ...
}
Similarly, AddMvvmSingleton also uses these annotations to ensure AOT compatibility.
This tells the trimmer exactly what members are needed at runtime, preventing accidental removal.
Publishing with AOT
Desktop Application
dotnet publish -c Release -p:PublishAot=true
With Trimming
dotnet publish -c Release -p:PublishTrimmed=true -p:PublishAot=true
Show Trim Warnings
dotnet publish -c Release -p:ShowTrimmedWarnings=true
Project Configuration
Example .csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>
</Project>
Avalonia Integration
Crystal.Avalonia template already enables compiled bindings by default:
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
This means XAML bindings are pre-compiled and do not use reflection at runtime. Combined with x:DataType, binding is fully AOT-friendly.
Troubleshooting
Trimmed Types Missing
If you see warnings about trimmed types:
- Add
[DynamicallyAccessedMembers]to generic method parameters - Use
Preserve<>attribute on needed types - Add entries to
rd.xmlfile for complex scenarios
Runtime Missing Types
If types are missing at runtime:
- Check that all View/ViewModel types are registered
- Verify module assemblies are not trimmed away
- Use
PreserveAllorPreserveMemberwhere needed
Further Reading
- Architecture — AOT & Trimming — compile-time type discovery, no assembly scanning
- .NET AOT Documentation
- Avalonia AOT Tips