Skip to content

Instantly share code, notes, and snippets.

@ghost1372
Last active July 23, 2025 10:48
Show Gist options
  • Save ghost1372/ffd706c760138d2a62c5a4d8f07410a7 to your computer and use it in GitHub Desktop.
Save ghost1372/ffd706c760138d2a62c5a4d8f07410a7 to your computer and use it in GitHub Desktop.
Native AOT

AOT Configuration and Tips

Project File Configuration

Include the following in your .csproj file to enable AOT (Ahead-of-Time compilation):

<PropertyGroup>
  <PublishAot>true</PublishAot>
  <IsAotCompatible>true</IsAotCompatible>
  <OptimizationPreference>speed</OptimizationPreference>
  <TrimMode>partial</TrimMode>
</PropertyGroup>

OptimizationPreference

Specifies how to optimize the AOT deployment:

  • <OptimizationPreference>speed</OptimizationPreference>: Prioritizes performance.
  • <OptimizationPreference>size</OptimizationPreference>: Reduces the binary size.
  • If not specified: Uses a balanced optimization between speed and size.

TrimMode

Controls how aggressively the trimmer removes unused code:

  • <TrimMode>full</TrimMode>: Trims everything to minimize file size, but may cause runtime issues if not careful.
  • <TrimMode>partial</TrimMode>: Trims only assemblies that have explicitly opted in to trimming, resulting in slightly larger output but better stability.

Native Methods/PInvoke

Use CsWin32 for calling Windows APIs via P/Invoke in AOT scenarios:

Set allowMarshaling to false in NativeMethods.json.

{
  "$schema": "https://aka.ms/CsWin32.schema.json",
  "public": true,
  "allowMarshaling": false
}

Using LibraryImport Instead of DllImport

DllImport is not supported in AOT. Use LibraryImport with unsafe code permissions:

public static partial class extLib
{
    [LibraryImport("myDll")]
    public static partial int SomeFunc(int arg);
}

ComboBox

DisplayMemberPath Issue

In AOT scenarios, DisplayMemberPath in ComboBox may not work properly.

Use GeneratedBindableCustomProperty to expose properties:

<ComboBox ItemsSource="{x:Bind ViewModel.TestList}" DisplayMemberPath="Name" />
[GeneratedBindableCustomProperty([nameof(Name)], [typeof(String)])]
internal partial record Person(string Name, int Age);

ItemsSource Binding Issues

When using ItemsSource with AOT (e.g., in ComboBox or ItemsView), runtime errors or data loss may occur at runtime.

Install the CsWinRT package in your project.

[!Note]

Including CsWinRT is recommended when targeting AOT, especially with Windows App SDK 1.7, where dependency resolution may not work as expected.

[!Note]

Always provide a DataTemplate with a DataType in ItemTemplate


Data Binding

Use x:Bind Instead of Binding

<TextBlock Text="{x:Bind ViewModel.TestInt32, Mode=OneWay}" />

Use GeneratedBindableCustomProperty if x:Bind Is Not an Option

Add x:DataType to your XAML page:

<Page
    x:Class="TestAotTips.Views.MainWindows.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:v="using:TestAotTips.ViewModels.MainWindows"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:DataType="v:MainPageViewModel"
    mc:Ignorable="d">

    <TextBlock Text="{Binding TestInt32}" />
</Page>

Add the attribute to your ViewModel class:

[GeneratedBindableCustomProperty]
public partial class MainPageViewModel : ObservableRecipient
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment