DEV Community

Cover image for [Showoff] Tired of DependencyProperty boilerplate? I built a Zero-Allocation Source Generator for WPF/MAUI with strict type safety.
kassyi
kassyi

Posted on

[Showoff] Tired of DependencyProperty boilerplate? I built a Zero-Allocation Source Generator for WPF/MAUI with strict type safety.

Hey everyone,

Let's face it: writing DependencyProperty in .NET UI frameworks is a chore. Typing out DependencyProperty.Register with 20 lines of boilerplate for a single property is tedious, error-prone, and severely clutters your codebase.

I wanted a frictionless DX, so I built a highly optimized Source Generator: Kassyi.Generators.DependencyProperty.

GitHub: Kassyi/DependencyPropertyGenerator
NuGet: Kassyi.Generators.DependencyProperty

1. The Highlights (What makes this different?)

  • 1-Line Generation: Just add [DependencyProperty<T>]. It generates the DP, properties, and callback registrations automatically.
  • Zero IDE Lag (Zero-Allocation): Completely eliminates Gen2 GC spikes during code generation. (More on this below).
  • Bulletproof Type Safety: Catch signature mismatches in your callbacks instantly at compile-time (DPG0001), completely eliminating silent runtime errors.
  • Framework Agnostic: Write the exact same attribute syntax for WPF, MAUI, Avalonia, Uno, WinUI 3, and UWP.

2. Show me the code

Instead of the usual DependencyProperty.Register nightmare, you only write this:


Before (The Boilerplate):

public static readonly DependencyProperty IsActiveProperty =
    DependencyProperty.Register(
        nameof(IsActive),
        typeof(bool),
        typeof(MyControl),
        new PropertyMetadata(false, OnIsActiveChanged));

public bool IsActive
{
    get => (bool)GetValue(IsActiveProperty);
    set => SetValue(IsActiveProperty, value);
}

private static void OnIsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ... }

Enter fullscreen mode Exit fullscreen mode

After:

[DependencyProperty<bool>("IsActive", DefaultValue = "false")]
public partial class MyControl : Control
{
    // QoL Feature: The generator automatically detects methods named "On{Prop}Changed" 
    // and magically hooks them up to the PropertyMetadata under the hood!
    partial void OnIsActiveChanged(bool oldValue, bool newValue)
    {
        // Your logic here. No casting, no DependencyObject/EventArgs boilerplate.
    }
}

Enter fullscreen mode Exit fullscreen mode

3. Under the Hood: Extreme "Zero-Allocation" Architecture

This project is originally a fork of the excellent HavenDV's generator. While the original is fantastic, I encountered a major pain point when scaling it to massive enterprise solutions: IDE performance degradation.

Source Generators run in the background on almost every keystroke. If a generator relies heavily on intermediate string concatenations, it triggers constant Garbage Collection (GC) spikes, leading to micro-stutters and IDE freezes in Visual Studio or Rider.

To solve this, I completely rewrote the code synthesis engine to be 100% zero-allocation.

  • I built a custom engine using ref struct based components (ClassScope and SourceWriter).
  • Intermediate string allocations and heap allocations are completely bypassed.

The result? 100% elimination of Gen2 GC spikes, a +30% increase in execution speed, and +62.4% higher throughput. You can drop this into a solution with thousands of properties, and your IDE will remain buttery smooth.

4. Bulletproof Compile-Time Type Safety

A dangerous flaw in older generation approaches was silent runtime errors. If you made a typo in the callback signature (e.g., wrong argument types), the generator would fail silently, register a null callback under the hood, and cause debugging nightmares at runtime.

This generator completely eliminates that class of bugs. Signature mismatches are now instantly caught via Roslyn diagnostics as compile-time errors (like DPG0001). If you see a red squiggle in your editor, you fix it before ever hitting run.

5. Fully Leveraging Modern C# 11+

The library is designed to utilize modern C# features to keep your code as clean as possible:

  • Generic Attributes (C# 11+): No more messy typeof(T). You can write [DependencyProperty<string>] intuitively.
  • Target-Typed new(...) Expansion: Writing DefaultValueExpression = "new(42)" is dynamically evaluated and safely expanded into a fully qualified constructor via AST parsing.
  • Auto-Synthesized XML Docs: Simply pass a Description parameter, and the generator builds the IntelliSense XML documentation comments for you.

6. Write Once, Run Anywhere (Multi-Framework Support)

This isn't just for WPF. The internal strategy pattern automatically abstracts away the underlying API differences across frameworks (such as Avalonia's DirectProperty, MAUI's BindableProperty, or subtle callback signature variations).

You can use the exact same attribute syntax across:

  • WPF
  • .NET MAUI
  • Avalonia
  • Uno Platform
  • WinUI 3
  • UWP

Feedback Welcome!

The project is fully open-source under the MIT License, so feel free to use it in your personal projects or massive commercial enterprise solutions.

I know that adopting a new OSS library can be daunting, so I've provided comprehensive documentation and specifications (available in both English and Japanese) covering basic usage, attribute details, and the internal architecture.

If you’re working with WPF, MAUI, or Avalonia and are tired of the boilerplate, I’d love for you to give it a try. I am highly open to feedback, code reviews, and discussions on edge cases!

Top comments (0)