Xamlizer 1.0.10
dotnet add package Xamlizer --version 1.0.10
NuGet\Install-Package Xamlizer -Version 1.0.10
<PackageReference Include="Xamlizer" Version="1.0.10" />
<PackageVersion Include="Xamlizer" Version="1.0.10" />
<PackageReference Include="Xamlizer" />
paket add Xamlizer --version 1.0.10
#r "nuget: Xamlizer, 1.0.10"
#:package Xamlizer@1.0.10
#addin nuget:?package=Xamlizer&version=1.0.10
#tool nuget:?package=Xamlizer&version=1.0.10
Xamlizer
A Roslyn source generator for .NET MAUI that reads XAML resource dictionaries and generates typed C# constants for every x:Key attribute, eliminating magic strings when looking up resources in code.
Overview
XAML resource dictionaries are typically consumed in C# using string literals:
var color = (Color)Application.Current.Resources["Primary"];
If the key is mistyped or renamed in the XAML file, the error only surfaces at runtime. Xamlizer generates a static class at compile time so the same lookup becomes:
var color = (Color)Application.Current.Resources[ColorsKeys.Color.Primary];
The constant ColorsKeys.Color.Primary is checked by the compiler. Rename the resource in XAML and the build fails immediately, pointing you to every site that needs updating.
Setup
NuGet (recommended)
Install via NuGet:
<PackageReference Include="Xamlizer" Version="1.0.10" />
The package automatically imports build/Xamlizer.targets, which wires up the XamlizerInput item group. No additional MSBuild setup is required.
Local project reference
When referencing Xamlizer directly as a project (for example, from a sample app in the same repository), add the project reference as an analyzer and import the targets file manually:
<ItemGroup>
<ProjectReference Include="path\to\Xamlizer\Xamlizer.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>
<Import Project="path\to\Xamlizer\build\Xamlizer.targets" />
Opting files in
Regardless of how Xamlizer is referenced, opt individual XAML resource dictionaries into key generation by adding them as XamlizerInput items in your .csproj. These must appear before the <Import> of Xamlizer.targets (or before the closing </Project> tag when using the NuGet package):
<ItemGroup>
<XamlizerInput Include="Resources\Styles\Colors.xaml" />
<XamlizerInput Include="Resources\Styles\Styles.xaml" />
</ItemGroup>
Glob patterns are supported, so you can include an entire folder at once:
<ItemGroup>
<XamlizerInput Include="Resources\Styles\*.xaml" />
</ItemGroup>
Generated Output
Given a resource dictionary named Colors.xaml:
<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<Color x:Key="Primary">#512BD4</Color>
<Color x:Key="Secondary">#DFD8F7</Color>
<Color x:Key="Tertiary">#2B0B98</Color>
<SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource Primary}"/>
<SolidColorBrush x:Key="SecondaryBrush" Color="{StaticResource Secondary}"/>
</ResourceDictionary>
Xamlizer generates the following class at compile time:
// <auto-generated/>
namespace YourApp
{
public static class ColorsKeys
{
public static class Color
{
public const string Primary = "Primary";
public const string Secondary = "Secondary";
public const string Tertiary = "Tertiary";
}
public static class SolidColorBrush
{
public const string PrimaryBrush = "PrimaryBrush";
public const string SecondaryBrush = "SecondaryBrush";
}
}
}
Resources are grouped by their element type (the XML local name). Within each group, constants appear in the order they occur in the file. If the same type appears in multiple places in the file (common with Color blocks separated by SolidColorBrush entries), all keys for that type are collected into one nested class in first-occurrence order.
The generated class name is the file name + Keys suffix (for example, Colors.xaml produces ColorsKeys). The namespace is the same as the project root namespace.
Using the Generated Code
Look up a resource using the generated constant instead of a string literal:
// Before
var color = (Color)Application.Current!.Resources["Primary"];
// After
var color = (Color)Application.Current!.Resources[ColorsKeys.Color.Primary];
You can also store lists of keys without any string duplication:
private static readonly string[] ThemeColors =
[
ColorsKeys.Color.Primary,
ColorsKeys.Color.Secondary,
ColorsKeys.Color.Tertiary,
];
What Gets Processed
Xamlizer processes only elements that have an x:Key attribute. Elements without one are ignored, including:
- The root
ResourceDictionaryelement - Implicit styles (defined with
TargetTypeand nox:Key) - Any other element that does not carry an
x:Key
If a XAML file contains no elements with x:Key, no class is generated for that file.
Identifier Sanitization
XAML resource keys can contain characters that are not valid in C# identifiers. Xamlizer applies the following rules when converting a key to a constant name:
| Situation | Rule |
|---|---|
| Key starts with a digit | A _ is prepended |
| Key contains a character that is not a letter, digit, or underscore | That character is replaced with _ |
| Sanitized name is a C# keyword | A _ is prepended |
| Two keys in the same type group sanitize to the same name | A numeric suffix is appended (_1, _2, ...) |
The original key string is always preserved as the constant's value, regardless of how the name is sanitized:
// XAML: <Color x:Key="100Gray">...</Color>
public const string _100Gray = "100Gray";
// XAML: <Color x:Key="class">...</Color>
public const string _class = "class";
Diagnostics
| ID | Severity | Description |
|---|---|---|
XAM001 |
Error | The XAML file could not be parsed. The message includes the file path and the XML parser error. This usually indicates malformed XML in the resource dictionary. |
Limitations
Same-filename XAML files in different folders. Generated file names are derived from the file's path relative to the project directory (for example,
Resources/Styles/Colors.xamlproducesResources_Styles_ColorsKeys.g.cs). This ensures uniqueness across folders. However, both files still produce a class with the same short name inside the same namespace, so you will get a compiler error. Rename one of the files to resolve this.Non-literal
x:Keyvalues. Xamlizer readsx:Keyas a plain string attribute. Dynamic or markup-extension-based keys (such asx:Key="{x:Type SomeType}") are not supported and are skipped.Build action requirement. Files must be explicitly opted in using
<XamlizerInput Include="..." />in your project file. When the Xamlizer NuGet package is installed, thebuild/Xamlizer.targetsfile is automatically imported and collects the opted-in paths into a build property (XamlizerInputFiles) that the generator reads. Files that appear inAdditionalFilesby other means are not processed unless they also appear asXamlizerInputitems.
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.