This guide explains which build switches control InitializeComponent generation in Avalonia projects, how that changes when AXSG is enabled, and how AXSG IL weaving changes the migration story for legacy AvaloniaXamlLoader.Load(...) code-behind.
For AXSG-backed class-backed XAML:
<AvaloniaXamlCompilerBackend>SourceGen</AvaloniaXamlCompilerBackend>InitializeComponent(bool loadXaml = true)AvaloniaXamlLoader wrappers over timeLoad(this) or Load(serviceProvider, this) call sites during migrationAvaloniaNameGeneratorIsEnabled as the legacy Avalonia path, not the AXSG pathThis includes App.axaml.cs. The application root must follow the same rule as any other class-backed AXAML file.
InitializeComponentThere are two different systems that can participate in class-backed XAML initialization:
The main switches are:
| Switch | Layer | What it means |
|---|---|---|
AvaloniaXamlCompilerBackend |
project MSBuild property | Chooses the XAML compiler backend. SourceGen selects AXSG; XamlIl keeps the standard Avalonia path. |
AvaloniaSourceGenCompilerEnabled |
project MSBuild property | Explicit AXSG master enable switch. Usually implied by AvaloniaXamlCompilerBackend=SourceGen. |
EnableAvaloniaXamlCompilation |
project MSBuild property | Controls Avalonia XamlIl compilation. AXSG build integration disables this when SourceGen is active. |
AvaloniaNameGeneratorIsEnabled |
project MSBuild property | Controls Avalonia's legacy name generator that participates in the classic InitializeComponent path. |
XamlSourceGenIlWeavingEnabled / AvaloniaSourceGenIlWeavingEnabled |
project MSBuild property | Enables AXSG post-compile rewriting of supported AvaloniaXamlLoader.Load(...) call sites to generated AXSG initializer helpers. |
AXAML_SOURCEGEN_BACKEND |
conditional compilation symbol | Defined by AXSG build integration when the active backend is AXSG. Use it to guard compatibility fallback code. |
AvaloniaNameGeneratorIsEnabled really meansAvaloniaNameGeneratorIsEnabled is not the AXSG switch. It belongs to the legacy Avalonia build path.
When AXSG is active, XamlToCSharpGenerator.Build turns it off so the project does not end up with two competing class initialization paths.
That is the important distinction:
AvaloniaNameGeneratorIsEnabled=true means the classic Avalonia path is still allowed to generate its helper surfaceAvaloniaXamlCompilerBackend=SourceGen means AXSG is responsible for generated class-backed initializationTypical shape:
<PropertyGroup>
<AvaloniaXamlCompilerBackend>XamlIl</AvaloniaXamlCompilerBackend>
<EnableAvaloniaXamlCompilation>true</EnableAvaloniaXamlCompilation>
<AvaloniaNameGeneratorIsEnabled>true</AvaloniaNameGeneratorIsEnabled>
</PropertyGroup>
In this mode:
AvaloniaXamlLoader.Load(this) is compatible with the active backendInitializeComponent is not the active pathTypical shape:
<PropertyGroup>
<AvaloniaXamlCompilerBackend>SourceGen</AvaloniaXamlCompilerBackend>
</PropertyGroup>
With AXSG build integration, that implies the effective behavior is:
AvaloniaSourceGenCompilerEnabled=trueEnableAvaloniaXamlCompilation=falseAvaloniaNameGeneratorIsEnabled=falseIn this mode:
InitializeComponent(bool loadXaml = true) methodAvaloniaXamlLoader.Load(...) call sites can be rewritten to the generated AXSG initializer helpersAvaloniaXamlLoader.Load(this) wrapper still bypasses the generated AXSG pathThis is the migration-friendly shape when one code-behind file still has to build in both worlds.
Recommended pattern:
public MainWindow()
{
InitializeComponent();
}
#if !AXAML_SOURCEGEN_BACKEND
private void InitializeComponent()
{
global::Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);
}
#endif
In this mode:
AvaloniaXamlLoader.Load(this) is not directly compatible without IL weavingFor AXSG class-backed XAML, the source-generated partial already contains the generated object-graph population code.
If your code-behind keeps:
private void InitializeComponent()
{
global::Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);
}
then this constructor:
public MainWindow()
{
InitializeComponent();
}
binds to the hand-written parameterless method, not the AXSG-generated InitializeComponent(bool loadXaml = true).
That makes raw AvaloniaXamlLoader.Load(this) incompatible with AXSG as the active class initialization path because it:
The issue is not just "duplicate code". It is that the wrong method wins overload resolution.
When AXSG IL weaving is enabled, supported legacy call sites are rewritten after compile:
AvaloniaXamlLoader.Load(this) becomes the generated AXSG initializer helper for that same typeAvaloniaXamlLoader.Load(serviceProvider, this) becomes the service-provider-aware generated AXSG initializer helperThat means a common legacy wrapper can stay in source temporarily and still run on AXSG's generated initialization path at runtime.
This is a migration bridge, not the preferred end-state. The clearest long-term AXSG style is still to remove the manual wrapper and call the generated InitializeComponent() directly.
Preferred:
public MainWindow()
{
InitializeComponent();
}
The same applies to App:
public partial class App : Application
{
public App()
{
InitializeComponent();
}
}
Compatibility alternative during migration:
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
That source shape is supported when AXSG IL weaving is enabled, but it still relies on a build-time rewrite pass instead of the direct generated method.
Use:
public MainWindow()
{
InitializeComponent();
}
#if !AXAML_SOURCEGEN_BACKEND
private void InitializeComponent()
{
global::Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);
}
#endif
If you explicitly set:
<AvaloniaNameGeneratorIsEnabled>true</AvaloniaNameGeneratorIsEnabled>
while also enabling AXSG, you are re-enabling a legacy path that AXSG normally disables to avoid conflicts. That is not the recommended AXSG configuration.
For normal AXSG app usage, do not force the name generator back on.
<ItemGroup>
<PackageReference Include="XamlToCSharpGenerator" Version="x.y.z" />
</ItemGroup>
<PropertyGroup>
<AvaloniaXamlCompilerBackend>SourceGen</AvaloniaXamlCompilerBackend>
</PropertyGroup>
And in app startup:
using XamlToCSharpGenerator.Runtime;
public static AppBuilder BuildAvaloniaApp() =>
AppBuilder.Configure<App>()
.UsePlatformDetect()
.UseAvaloniaSourceGeneratedXaml();
If a view still behaves like classic Avalonia loading after switching to AXSG:
AvaloniaXamlCompilerBackend=SourceGen..UseAvaloniaSourceGeneratedXaml().XamlSourceGenIlWeavingEnabled is true if you expect legacy wrappers to be bridged automatically.AvaloniaXamlLoader.Load(this) is only present under #if !AXAML_SOURCEGEN_BACKEND when mixed-backend support is intentional and weaving is not the chosen bridge.obj/... contains AXSG-generated InitializeComponent(bool loadXaml = true) and the __InitializeXamlSourceGenComponent(...) helper overloads.