Skip to content

[Roadmap] NativeAOT Support via Splat Cleanup & ReactiveUI Source Generation #4243

@glennawatson

Description

@glennawatson

Description:

This issue tracks the roadmap for achieving full NativeAOT compatibility in ReactiveUI.

Context & Previous Attempts

We recently reviewed PR #4242 (submitted by a community member), which sought to enable AOT support by annotating the existing reflection-heavy codebase with [RequiresUnreferencedCode] and [DynamicallyAccessedMembers] attributes. This was also mentioned in discussion #4210

While we appreciate the significant effort involved in that PR, we made the hard decision to close it.

The primary reason is that annotating the existing codebase simply adds "trim warnings" while preserving the underlying reflection paths. This results in code that is "linker-aware" but not truly "linker-safe" or performant. It does not solve the fundamental issue that runtime reflection is antithetical to the goals of AOT (performance and size reduction).

The Path Forward: Source Generation

Instead of maintaining a complex web of suppression attributes and warnings, our goal is to replace these reflection paths entirely with compile-time logic using Source Generators.

We will adopt the architectural approach successfully prototyped in [ReactiveMarbles](https://github.com/reactivemarbles). This involves generating strongly-typed code at compile time for operations that historically required runtime introspection, such as property binding and view registration.

Roadmap

Phase 1: Splat Maintenance (Prerequisite)

  • Objective: Clean up Splat dependencies and warnings.
  • Action: Remove redundant IL/Trim warnings within Splat.
  • Rationale: Splat is the foundation for our Service Location and logging. We need to ensure it doesn't emit redundant or confusing warnings that would clutter the build output when we start working on the main ReactiveUI library. We do have a reflection free source generation layer in ReactiveMarbles, but the issue is in Splat we have compatibility layers with other DI engines and most of those require reflection, so some of the IL warning suppressions will have to remain.

Phase 2: ReactiveUI Source Generation

  • Objective: Eliminate heavy reflection usage in core ReactiveUI features.
  • Key Areas:
  • Property Binding: Replace reflection-based binding with generated setters/getters (based on ReactiveMarbles.ObservableEvents patterns).
  • ViewLocator: Replace DefaultViewLocator reflection (scanning assemblies for IViewFor<T>) with a Source Generator that registers views at compile time.
  • WhenAny: Optimize observable chains to remove runtime expression tree compilation.
  • Windows Platforms: Update WPF, WinForms, and WinUI to consume these generated paths.

By skipping the "Annotation Phase" and moving straight to "Source Generation," we avoid technical debt and deliver a truly AOT-compatible library.

Task List

  • Phase 1 (Splat): Audit and remove redundant IL/Trim warnings in the Splat library.
  • Phase 2 (RxUI): Create a Source Generator for IViewFor registration (ViewLocator).
  • Phase 2 (RxUI): Create a Source Generator for Type-safe Property Binding.
  • Phase 2 (RxUI): Update Windows/Desktop platforms (WPF, WinUI, WinForms) to utilize generated code paths.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions