Skip to content

Make XAML Source Generator (XSG) the default inflator for .NET 11#33524

Merged
rmarinho merged 13 commits intonet11.0from
feature/xsf-default-inflator-net11
Feb 6, 2026
Merged

Make XAML Source Generator (XSG) the default inflator for .NET 11#33524
rmarinho merged 13 commits intonet11.0from
feature/xsf-default-inflator-net11

Conversation

@StephaneDelcroix
Copy link
Contributor

@StephaneDelcroix StephaneDelcroix commented Jan 14, 2026

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description

This PR makes the XAML Source Generator (XSG) the default XAML inflator for .NET 11, replacing the previous configuration-based defaults (Runtime in Debug, XamlC in Release).

Changes

1. Default Inflator Change

  • Changed MauiXamlInflator default from Runtime (Debug) / XamlC (Release) to SourceGen for all configurations
  • Added warning MAUI1001 when explicitly setting MauiXamlInflator to a non-SourceGen value, suggesting to remove the property

2. Template Updates

  • Removed explicit <MauiXamlInflator>SourceGen</MauiXamlInflator> from all 9 template files since SourceGen is now the default

3. Deprecate [XamlCompilation] Attribute

  • XamlCompilationAttribute and XamlCompilationOptions are now marked [Obsolete] with a warning in .NET 11
  • In .NET 12+, the attribute will become an error (wrapped with #if !NET12_0_OR_GREATER)
  • Backward compatibility code still honors the attribute in .NET 11

4. Sample Project Fixes

  • Several sample projects that use deprecated APIs now explicitly set <MauiXamlInflator>Runtime</MauiXamlInflator> to avoid SourceGen surfacing obsolete API usage as errors

5. Documentation

  • Added MauiXamlInflator section to docs/design/FeatureSwitches.md

Breaking Changes

  1. Default inflator changed: Projects without explicit MauiXamlInflator will now use SourceGen instead of Runtime/XamlC
  2. [XamlCompilation] is deprecated: Shows warning in .NET 11, will be error in .NET 12. Users should migrate to MSBuild properties/metadata:
    <PropertyGroup>
      <MauiXamlInflator>SourceGen</MauiXamlInflator>
    </PropertyGroup>
    
    <!-- Or per-file: -->
    <MauiXaml Update="MyPage.xaml" Inflator="Runtime" />

Migration Path

For users who want to keep the old behavior:

<PropertyGroup>
  <!-- Use Runtime inflation (like Debug mode previously) -->
  <MauiXamlInflator>Runtime</MauiXamlInflator>
</PropertyGroup>

Copilot AI review requested due to automatic review settings January 14, 2026 07:52
@StephaneDelcroix StephaneDelcroix added this to the .NET 11.0-preview1 milestone Jan 14, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes XAML Source Generator (SourceGen) the default XAML inflator for .NET 11, replacing the previous configuration-based defaults (Runtime for Debug, XamlC for Release). It also deprecates the [XamlCompilation] attribute by making it an error and removes all backward compatibility code.

Changes:

  • Changed default MauiXamlInflator from configuration-based (Runtime/XamlC) to SourceGen for all configurations
  • Removed explicit <MauiXamlInflator>SourceGen</MauiXamlInflator> from 9 template project files (now redundant)
  • Made XamlCompilationAttribute and XamlCompilationOptions obsolete with error: true
  • Removed _MAUIXAML_SOURCEGEN_BACKCOMPAT flag and all associated backward compatibility code
  • Added deprecation warning MAUI1001 for Runtime/XamlC inflators
  • Added comprehensive documentation for MauiXamlInflator in FeatureSwitches.md

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Templates/src/templates/maui-multiproject/MauiApp.1/MauiApp.1.csproj Removed MauiXamlInflator property (now default)
src/Templates/src/templates/maui-multiproject/MauiApp.1.iOS/MauiApp.1.iOS.csproj Removed MauiXamlInflator property (now default)
src/Templates/src/templates/maui-multiproject/MauiApp.1.WinUI/MauiApp.1.WinUI.csproj Removed MauiXamlInflator property (now default)
src/Templates/src/templates/maui-multiproject/MauiApp.1.Mac/MauiApp.1.Mac.csproj Removed MauiXamlInflator property (now default)
src/Templates/src/templates/maui-multiproject/MauiApp.1.Droid/MauiApp.1.Droid.csproj Removed MauiXamlInflator property (now default)
src/Templates/src/templates/maui-mobile/MauiApp.1.csproj Removed MauiXamlInflator property (now default)
src/Templates/src/templates/maui-lib/MauiLib1.csproj Removed MauiXamlInflator property (now default)
src/Templates/src/templates/maui-blazor/MauiApp.1.csproj Removed MauiXamlInflator property (now default)
src/Templates/src/templates/maui-blazor-solution/MauiApp.1/MauiApp.1.csproj Removed MauiXamlInflator property (now default)
src/Controls/src/Xaml/XamlCompilationAttribute.cs Removed conditional compilation, made attribute error unconditionally, removed XamlCExtensions class
src/Controls/src/SourceGen/CodeBehindCodeWriter.cs Removed backward compatibility code for xaml-comp processing instruction and conditional XamlCompilation attribute generation
src/Controls/src/Build.Tasks/nuget/buildTransitive/netstandard2.0/Microsoft.Maui.Controls.targets Changed default inflator to SourceGen, updated warning MAUI1001, removed informational message
src/Controls/src/Build.Tasks/XamlCTask.cs Removed assembly/module/type-level XamlCompilationAttribute scanning code
docs/design/FeatureSwitches.md Added comprehensive MauiXamlInflator documentation with examples and breaking changes
Directory.Build.props Removed _MAUIXAML_SOURCEGEN_BACKCOMPAT property group
Comments suppressed due to low confidence (1)

src/Controls/src/Build.Tasks/nuget/buildTransitive/netstandard2.0/Microsoft.Maui.Controls.targets:112

  • The warning condition should also check that MauiXamlInflator contains either 'runtime' or 'xamlc' to avoid false positives. Currently, the condition will trigger a warning for ANY non-empty value that doesn't contain 'sourcegen', including potentially invalid values or future new inflator types. Consider changing the condition to explicitly check for the deprecated inflators:

Condition="'$(MauiXamlInflator)' != '' And ($([System.String]::new('$(MauiXamlInflator)').ToLowerInvariant().Contains('runtime')) Or $([System.String]::new('$(MauiXamlInflator)').ToLowerInvariant().Contains('xamlc')))

This would only warn when actually using the deprecated Runtime or XamlC inflators.

    <_MauiInjectXamlCssAdditionalFilesDependsOn>

@StephaneDelcroix StephaneDelcroix changed the title Make XAML Source Generator (XSF) the default inflator for .NET 11 Make XAML Source Generator (XSG) the default inflator for .NET 11 Jan 14, 2026
@StephaneDelcroix StephaneDelcroix force-pushed the feature/xsf-default-inflator-net11 branch from a2f8ec9 to 8080e05 Compare January 14, 2026 12:57
@rmarinho
Copy link
Member

/rebase

@github-actions github-actions bot force-pushed the feature/xsf-default-inflator-net11 branch from 258663c to b9a8f53 Compare January 16, 2026 13:35
@rmarinho
Copy link
Member

/rebase

- Change default MauiXamlInflator from Runtime/XamlC to SourceGen
- Remove explicit MauiXamlInflator from all templates (now uses default)
- Deprecate [XamlCompilation] attribute with error (use MSBuild metadata instead)
- Remove _MAUIXAML_SOURCEGEN_BACKCOMPAT flag and all conditional code
- Add MAUI1001 warning when using deprecated Runtime/XamlC inflators
- Document breaking changes in FeatureSwitches.md
- Restore _MAUIXAML_SOURCEGEN_BACKCOMPAT flag (will be removed in .NET 12)
- Backcompat code now uses #if _MAUIXAML_SOURCEGEN_BACKCOMPAT
- [XamlCompilation] attribute remains usable in .NET 11
- Deprecation with error will happen in .NET 12 (NET12_0_OR_GREATER)
- NET11: [XamlCompilation] produces Obsolete warning but still works
- NET12: [XamlCompilation] produces Obsolete error and becomes no-op
- XamlCompilationAttribute.cs uses NET11_0/NET12_0_OR_GREATER for Obsolete attrs
- SourceGen/Build.Tasks use _MAUIXAML_SOURCEGEN_BACKCOMPAT (netstandard2.0)
- [XamlCompilation] is deprecated (warning) in NET11, no-op (error) in NET12
- Remove backcompat flag from Directory.Build.props
- Use #if !NET12_0_OR_GREATER for backcompat code
- Add #pragma disable CS0618 for internal usage of deprecated types
- SourceGen: xaml-comp processing instruction honored in NET11, ignored in NET12
- XamlCTask: [XamlCompilation] scanning active in NET11, removed in NET12
- Suppress CS0618 warning in test's AssemblyInfo.cs for deprecated [XamlCompilation]
- Add pragma to SourceGen when emitting [XamlCompilation(Skip)]
- Update ValidateOnly test: XAML no longer embedded with SourceGen default
- Controls.Sample: Already fixed (uses Runtime inflator)
- Controls.Sample.Embedding: Set Runtime inflator (nullability issues)
- Controls.Sample.Profiling: Set Runtime inflator + pragma for XamlCompilation
- Essentials.Sample: Set Runtime inflator + pragma for XamlCompilation
- DeviceTests.Runners: Set Runtime inflator (deprecated Frame)
- DeviceRunner: Add pragma for deprecated XamlCompilation
- Add per-file NoWarn for CS0612 on XAML files using obsolete APIs (Device, NamedSize)
- Fix CS8622 nullability mismatches on event handlers (object -> object?)
- Fix CS8600/CS8602 nullability issues with sender casts (add null-forgiving)
- Add ButtonPage.xaml to Runtime inflator list (XSG NaN bug)
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 147 out of 147 changed files in this pull request and generated 5 comments.

#pragma warning disable CS0618 // XamlCompilation is deprecated but still generated for backcompat
if (!addXamlCompilationAttribute && (xamlInflators & XamlInflator.XamlC) == 0 && !alreadyHasXamlCompilationAttribute)
sb.AppendLine($"\t[global::Microsoft.Maui.Controls.Xaml.XamlCompilation(global::Microsoft.Maui.Controls.Xaml.XamlCompilationOptions.Skip)]");
sb.AppendLine($"\t#pragma warning disable CS0618\n\t[global::Microsoft.Maui.Controls.Xaml.XamlCompilation(global::Microsoft.Maui.Controls.Xaml.XamlCompilationOptions.Skip)]\n\t#pragma warning restore CS0618");
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pragma warnings and attribute are embedded in a single string with escaped newlines. Consider using multiple AppendLine calls for better readability and maintainability.

Suggested change
sb.AppendLine($"\t#pragma warning disable CS0618\n\t[global::Microsoft.Maui.Controls.Xaml.XamlCompilation(global::Microsoft.Maui.Controls.Xaml.XamlCompilationOptions.Skip)]\n\t#pragma warning restore CS0618");
{
sb.AppendLine("\t#pragma warning disable CS0618");
sb.AppendLine("\t[global::Microsoft.Maui.Controls.Xaml.XamlCompilation(global::Microsoft.Maui.Controls.Xaml.XamlCompilationOptions.Skip)]");
sb.AppendLine("\t#pragma warning restore CS0618");
}

Copilot uses AI. Check for mistakes.
void OnSwipeViewTransitionModeChanged(object? sender, EventArgs e)
{
SwipeTransitionMode transitionMode = (SwipeTransitionMode)((EnumPicker)sender).SelectedItem;
SwipeTransitionMode transitionMode = (SwipeTransitionMode)((EnumPicker)sender!).SelectedItem!;
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple null-forgiving operators and casts on a single line reduce readability. Consider breaking this into separate lines with intermediate variables.

Suggested change
SwipeTransitionMode transitionMode = (SwipeTransitionMode)((EnumPicker)sender!).SelectedItem!;
var picker = (EnumPicker)sender!;
var selectedItem = picker.SelectedItem;
SwipeTransitionMode transitionMode = (SwipeTransitionMode)selectedItem!;

Copilot uses AI. Check for mistakes.
var picker = (Picker)sender!;

switch (picker.SelectedItem.ToString())
switch (picker.SelectedItem!.ToString())
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using ToString() on a potentially null object after null-forgiving operator can mask null reference issues. Consider using pattern matching or explicit null checking instead.

Copilot uses AI. Check for mistakes.
<!-- These XAML files have XSG parsing issues, use Runtime inflator until fixed -->
<!-- Must be after Maui.InTree.props to properly override the globbed items -->
<ItemGroup>
<MauiXaml Remove="Pages/Controls/SwipeViewGalleries/*.xaml;Pages/Others/StyleSheetsPage.xaml;Pages/Others/TwoPaneViewPage.xaml;Pages/Controls/ButtonPage.xaml;Pages/Controls/RadioButtonGalleries/RadioButtonContentGallery.xaml" />
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long semicolon-separated list of paths is difficult to maintain. Consider using separate <MauiXaml Remove> elements for each path or pattern for better readability.

Suggested change
<MauiXaml Remove="Pages/Controls/SwipeViewGalleries/*.xaml;Pages/Others/StyleSheetsPage.xaml;Pages/Others/TwoPaneViewPage.xaml;Pages/Controls/ButtonPage.xaml;Pages/Controls/RadioButtonGalleries/RadioButtonContentGallery.xaml" />
<MauiXaml Remove="Pages/Controls/SwipeViewGalleries/*.xaml" />
<MauiXaml Remove="Pages/Others/StyleSheetsPage.xaml" />
<MauiXaml Remove="Pages/Others/TwoPaneViewPage.xaml" />
<MauiXaml Remove="Pages/Controls/ButtonPage.xaml" />
<MauiXaml Remove="Pages/Controls/RadioButtonGalleries/RadioButtonContentGallery.xaml" />

Copilot uses AI. Check for mistakes.
MainLayout.IsEnabled = !MainLayout.IsEnabled;

((Button)sender).Text = MainLayout.IsEnabled ? "Disable Layout" : "Enable Layout";
((Button)sender!).Text = MainLayout.IsEnabled ? "Disable Layout" : "Enable Layout";
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct cast with null-forgiving operator assumes sender is always a Button. Consider using pattern matching (if (sender is Button button)) for safer type checking.

Copilot uses AI. Check for mistakes.
Copy link
Member

@rmarinho rmarinho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Well-documented deprecation path with appropriate warnings and clear migration guidance.

Suggestions for follow-up:

  1. Modernize sample projects: Consider a follow-up PR to update the sample projects (Controls.Sample, etc.) to remove usage of deprecated APIs like Device and NamedSize. This would eliminate the need for the 30+ NoWarn="0612" suppressions in the csproj files, making the samples better references for users adopting SourceGen.

  2. CodeBehindCodeWriter.cs readability: The inline pragma warning string could be split into multiple AppendLine calls for better readability, as suggested in existing review comments.

Overall this is a solid change that moves the ecosystem forward with SourceGen as the default.

@rmarinho
Copy link
Member

rmarinho commented Feb 3, 2026

/azp run maui-pr-devicetests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rmarinho
Copy link
Member

rmarinho commented Feb 3, 2026

@StephaneDelcroix some failures building the device tests

D:\a\_work\1\s\src\Controls\tests\DeviceTests\Xaml\RadioButtonUsing.xaml.cs(6,3): error CS0618: 'XamlCompilationAttribute' is obsolete: 'XamlCompilationAttribute is deprecated. Specify xaml inflator using msbuild metadata on MauiXaml items in your .csproj: <MauiXaml Update="YourFile.xaml" Inflator="XamlC" />' [D:\a\_work\1\s\src\Controls\tests\DeviceTests\Controls.DeviceTests.csproj::TargetFramework=net11.0-windows10.0.19041.0]
D:\a\_work\1\s\src\Controls\tests\DeviceTests\Xaml\RadioButtonUsing.xaml.cs(6,19): error CS0618: 'XamlCompilationOptions' is obsolete: 'XamlCompilationOptions is deprecated. Specify xaml inflator using msbuild metadata on MauiXaml items in your .csproj: <MauiXaml Update="YourFile.xaml" Inflator="XamlC" />' [D:\a\_work\1\s\src\Controls\tests\DeviceTests\Controls.DeviceTests.csproj::TargetFramework=net11.0-windows10.0.19041.0]

@rmarinho
Copy link
Member

rmarinho commented Feb 3, 2026

/azp run maui-pr-uitests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@rmarinho rmarinho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some failures building the device tests

@rmarinho
Copy link
Member

rmarinho commented Feb 4, 2026

@copilot can you fix the device tests failures ?

D:\a\_work\1\s\src\Controls\tests\DeviceTests\Xaml\RadioButtonUsing.xaml.cs(6,3): error CS0618: 'XamlCompilationAttribute' is obsolete: 'XamlCompilationAttribute is deprecated. Specify xaml inflator using msbuild metadata on MauiXaml items in your .csproj: <MauiXaml Update="YourFile.xaml" Inflator="XamlC" />' [D:\a\_work\1\s\src\Controls\tests\DeviceTests\Controls.DeviceTests.csproj::TargetFramework=net11.0-windows10.0.19041.0]
D:\a\_work\1\s\src\Controls\tests\DeviceTests\Xaml\RadioButtonUsing.xaml.cs(6,19): error CS0618: 'XamlCompilationOptions' is obsolete: 'XamlCompilationOptions is deprecated. Specify xaml inflator using msbuild metadata on MauiXaml items in your .csproj: <MauiXaml Update="YourFile.xaml" Inflator="XamlC" />' [D:\a\_work\1\s\src\Controls\tests\DeviceTests\Controls.DeviceTests.csproj::TargetFramework=net11.0-windows10.0.19041.0]

Copy link
Contributor

Copilot AI commented Feb 4, 2026

@rmarinho I've opened a new pull request, #33894, to work on those changes. Once the pull request is ready, I'll request review from you.

…mpilation attribute (#33894)

Device tests were failing to build with CS0618 errors when the
deprecated `[XamlCompilation]` attribute was treated as an error during
CI builds.

## Changes

- Added `#pragma warning disable/restore CS0618` around
`[XamlCompilation]` attribute in `RadioButtonUsing.xaml.cs`
- Follows the same suppression pattern used in sample projects that need
to retain the deprecated attribute for testing purposes

The attribute remains deprecated as intended but no longer breaks the
build when warnings are treated as errors.

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rmarinho <1235097+rmarinho@users.noreply.github.com>
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rmarinho rmarinho merged commit 1ee63f2 into net11.0 Feb 6, 2026
186 of 211 checks passed
@rmarinho rmarinho deleted the feature/xsf-default-inflator-net11 branch February 6, 2026 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants