-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
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.ObservableEventspatterns). - ViewLocator: Replace
DefaultViewLocatorreflection (scanning assemblies forIViewFor<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
IViewForregistration (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.