Xamlizer 1.0.4-pre
See the version list below for details.
dotnet add package Xamlizer --version 1.0.4-pre
NuGet\Install-Package Xamlizer -Version 1.0.4-pre
<PackageReference Include="Xamlizer" Version="1.0.4-pre" />
<PackageVersion Include="Xamlizer" Version="1.0.4-pre" />
<PackageReference Include="Xamlizer" />
paket add Xamlizer --version 1.0.4-pre
#r "nuget: Xamlizer, 1.0.4-pre"
#:package Xamlizer@1.0.4-pre
#addin nuget:?package=Xamlizer&version=1.0.4-pre&prerelease
#tool nuget:?package=Xamlizer&version=1.0.4-pre&prerelease
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[ColorKeys.Color.Primary];
The constant ColorKeys.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
Install via NuGet:
<PackageReference Include="Xamlizer" Version="1.0.3-pre" />
Any xaml files you wish to use must be included as
AdditionalFilesin your.csproj. Fortunately if they are in theResources/Stylesdirectory of your maui app, this will already be the case.
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.
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,
];
Naming Conflicts
The generated class name uses a Keys suffix (for example, Colors.xaml produces ColorsKeys) to reduce collisions with common framework types. If a conflict still occurs, resolve it with a using alias:
using AppColors = YourApp.ColorsKeys;
var color = (Color)Application.Current!.Resources[AppColors.Color.Primary];
The alias can be placed at the top of a single file or in a GlobalUsings.cs file to apply it project-wide.
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 added as
<AdditionalFiles>in your project. MAUI's<MauiXaml>build action is separate and does not cause Xamlizer to process a file.
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.