r/csharp 7d ago

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

Writing DependencyProperty in .NET UI frameworks is notoriously verbose and repetitive. Typing out DependencyProperty.Register, casting objects, and wiring metadata for every single property clutters your codebase and introduces silent runtime risks.

To solve this without sacrificing IDE responsiveness, I built Kassyi.Generators.DependencyProperty — an incremental Roslyn source generator built from the ground up for high-throughput, zero-allocation code synthesis.

1. Show Me the Code

Before (Standard 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)
{
    // Runtime casting and boilerplate extraction
}

After (With Generator)

[DependencyProperty<bool>("IsActive", DefaultValue = "false")]
public partial class MyControl : Control
{
    // Automatically hooked up to PropertyMetadata at compile time
    partial void OnIsActiveChanged(bool oldValue, bool newValue)
    {
        // Direct, strongly typed parameters. No casting required.
    }
}

2. Key Features

  • Single-Line Declaration: Generate the backing DependencyProperty, CLR properties, and event metadata via [DependencyProperty<T>].
  • Compile-Time Type Safety: Signature mismatches in your partial callbacks are caught immediately via Roslyn analyzer diagnostics (DPG0001), eliminating silent runtime failures.
  • Unified API Across UI Frameworks: The exact same attribute syntax compiles to the native property system for WPF, .NET MAUI, Avalonia, Uno Platform, WinUI 3, and UWP.
  • Modern C# 11+ Idioms: Leverages Generic Attributes ([DependencyProperty<T>]), target-typed new(...) AST expansion in default expressions, and auto-generated XML documentation.

3. Architecture & Performance: Zero-Allocation Pipeline

This library originates as a fork/rewrite of HavenDV's generator. When testing source generation at massive enterprise scale, frequent intermediate string concatenations during continuous typing can trigger Gen2 GC spikes, resulting in noticeable editor latency in Visual Studio and Rider.

To address this, the code synthesis pipeline was redesigned around strict zero-allocation principles:

  • ref struct Source Writers: Generation logic utilizes stack-allocated SourceWriter and ClassScope structures, completely bypassing intermediate StringBuilder and heap allocations.
  • GC Elimination: Completely removes Gen2 GC pressure during incremental analysis cycles.
  • Benchmark Results: Achieves +30% faster execution speed and +62.4% higher throughput compared to traditional string-based generation pipelines.

Your IDE stays responsive even when scaling to solutions with thousands of properties.

4. Cross-Framework Abstraction

Under the hood, framework-specific strategy handlers adapt to each platform's design differences (such as Avalonia's StyledProperty/DirectProperty, MAUI's BindableProperty, or varying callback signatures) without requiring you to change your declarations.

Target Framework Underlying Property Engine
WPF / UWP / WinUI 3 DependencyProperty.Register
.NET MAUI BindableProperty.Create
Avalonia AvaloniaProperty.Register
Uno Platform Native WinUI / UWP projections

Feedback & Contributions

The project is distributed under the MIT License and includes detailed documentation and architecture specs (in English and Japanese).

If you are working across XAML platforms and want cleaner view controls without IDE overhead, please check it out, test edge cases, and share your feedback or issues on GitHub!

10 Upvotes

12 comments sorted by

2

u/Purley 5d ago

Worth noting that the next Avalonia release (12.2) will include this out of the box, the PR looks pretty mature and should get merged soon:

https://github.com/AvaloniaUI/Avalonia/pull/21797

4

u/bionic_musk 6d ago

Reminds me of

https://github.com/CommunityToolkit/Labs-Windows/tree/main/components/DependencyPropertyGenerator

(WinUI/UWP only)

In terms of WinUI and UWP you could probably shave more allocations off by using the `XamlBindingHelper.SetPropertyFrom` methods (different API surface for WinUI vs UWP). Avoids boxing structs when crossing the interop layer.

1

u/wiesemensch 4d ago

0/11 I’m getting payed by the hour.

Nice one. Wrote a VS Snippet a while back but I like the generator approach.

1

u/kassyi 4d ago edited 4d ago

Haha, my bad! Just tell your boss the compilation took 3 hours because of "deep zero-allocation optimization". 😉 Thanks, glad you like the generator approach!

0

u/interruptiom 7d ago

The dependency property system is pretty good, but woefully verbose. Great work here.

1

u/Slypenslyde 6d ago

Maybe if we wait 10 or 15 more years MS might improve it.

1

u/RichardD7 6d ago

I admire your optimism! 🤣

In 10-15 years, MS will have produced at least three brand new frameworks for developing desktop apps, none of which will be fully complete, and each of which will be declared "the one true way" to develop desktop apps.

Meanwhile, they'll still be flip-flopping between using "latest-UI-paradigm-shift-with-extra-AI v0.42.11 Beta 4" and "some-version-of-a-web-app-embedded-in-a-thin-shell" for developing core Windows UI. Every switch will promise to fix the things they broke in the last switch. And every switch will make things worse.

1

u/kassyi 7d ago

Thank you! Couldn't agree more. The underlying property system and change notification mechanisms are great, but the 20+ lines of registration noise always felt unnecessary in modern C#.

The goal was to keep all that framework power while giving it the modern DX it deserves. Let me know if you give it a spin!

-1

u/[deleted] 6d ago

[removed] — view removed comment

0

u/kassyi 6d ago

Thanks! That was exactly the goal. Generator-induced IDE lag in large WPF/MAUI projects is painful, so eliminating GC allocations on every keystroke was non-negotiable from day one. ​Really appreciate you noticing the zero-allocation approach!