Migrate to ReactiveUI 24 (.Reactive), Avalonia 12, and add WPF / WinUI 3 / Uno platform heads - #36
Merged
michaelstonis merged 3 commits intoAug 6, 2026
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…0985ee56d6c' into develop
…/WinUI 3/Uno platforms ReactiveUI 24 re-platformed onto ReactiveUI.Primitives and split into two distributions. Stellar adopts the .Reactive family (ReactiveUI.Reactive, ReactiveUI.Maui.Reactive, ReactiveUI.Blazor.Reactive): same new engine and performance as the default packages, but keeps the System.Reactive 7 types (Unit, IScheduler, Subject<T>) that Stellar's public API is built on. System.Reactive 7 becomes a direct dependency since ReactiveUI no longer flows it transitively. Consumers must add `global using ReactiveUI.Reactive;` (this also fixes code emitted by ReactiveGenerator and ReactiveUI.SourceGenerators, which still target the 23-era namespace). Avalonia.ReactiveUI has no ReactiveUI 24- or Avalonia 12-compatible release, so the dependency is removed: Stellar.Avalonia now provides its own IViewFor base classes, activation fetcher and UI-thread scheduler. That unlocks Avalonia 12.1.1 (Avalonia.Diagnostics dropped - discontinued after 11.3 and was referenced but unused). ReactiveUI 24 also dropped ReactiveViewCell; Stellar.Maui now ships its own. New platform heads, mirroring the existing per-platform pattern: - Stellar.Wpf (ReactiveUI.WPF.Reactive; targets net10.0-windows10.0.19041.0 - the plain net10.0-windows TFM silently resolves the package's .NET Framework assets via NU1701) - Stellar.WinUI (ReactiveUI.WinUI.Reactive + WindowsAppSDK 2.3.1; PRI/MSIX tooling disabled on non-Windows hosts so it cross-compiles) - Stellar.Uno (Uno.WinUI 6.6.176; no ReactiveUI 24-compatible Uno package exists, so it hand-rolls its activation fetcher and scheduler like Stellar.Avalonia) All three are in Stellar.sln, Stellar.slnf (ubuntu CI builds them; verified in a Linux container) and the nuget.yml release matrix, which previously would have skipped them silently on a v-tag. Other upgrades: CommunityToolkit.Maui 15.0.0, CommunityToolkit.Maui.Markup 8.0.0. Everything else was already latest; deliberate pins kept (Microsoft.CodeAnalysis.CSharp 5.0.0, stylecop beta). Validated: Release build of Stellar.slnf on macOS and Linux, 259/259 unit tests, pack rehearsal of all 9 non-MAUI release-matrix projects, and Release builds of Stellar.Maui/Stellar.Maui.PopUp for android and ios. MacCatalyst and Windows TFMs are compile-verified only (no local workload/ runner). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR upgrades StellarUI to the ReactiveUI 24 “.Reactive” package family (keeping System.Reactive types in the public API), removes Avalonia.ReactiveUI (replacing its missing ReactiveUI 24/Avalonia 12 compatibility with in-repo implementations), and adds new WPF/WinUI/Uno platform projects with hot-reload support and DI builder extensions.
Changes:
- Migrate package references to ReactiveUI 24 “.Reactive” packages and add explicit System.Reactive dependency.
- Add new Stellar.Wpf, Stellar.WinUI, and Stellar.Uno projects (base view types, view managers, schedulers, builder extensions, hot reload).
- Remove Avalonia.ReactiveUI/Avalonia.Diagnostics usage and implement Avalonia activation + UI-thread scheduling internally; update CI/solution files accordingly.
Reviewed changes
Copilot reviewed 58 out of 58 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| Stellar/Stellar.csproj | Switch core ReactiveUI dependency to ReactiveUI.Reactive + add System.Reactive. |
| Stellar/GlobalUsings.cs | Add ReactiveUI.Reactive global using for new ReactiveUI 24 surface. |
| Stellar.slnf | Include new WPF/WinUI/Uno projects in the solution filter. |
| Stellar.sln | Add WPF/WinUI/Uno projects and build configuration mappings. |
| Stellar.Wpf/WpfViewManager.cs | New WPF ViewManager with hot-reload binding re-registration. |
| Stellar.Wpf/WindowBase.cs | New WPF window base integrating Stellar lifecycle with ReactiveUI.WPF.Reactive. |
| Stellar.Wpf/UserControlBase.cs | New WPF user control bases integrating Stellar lifecycle (+ TDataModel variant). |
| Stellar.Wpf/Stellar.Wpf.csproj | New WPF package/project targeting net10.0-windows with ReactiveUI.WPF.Reactive. |
| Stellar.Wpf/HotReloadService.cs | New WPF hot-reload metadata update handler + event dispatch. |
| Stellar.Wpf/GlobalUsings.cs | New WPF project-wide usings for System.Reactive + ReactiveUI.Reactive. |
| Stellar.Wpf/Extensions/BuilderExtensions.cs | New WPF DI extensions to initialize ReactiveUI services and enable hot reload. |
| Stellar.WinUI/WinUIViewManager.cs | New WinUI ViewManager with hot-reload binding re-registration. |
| Stellar.WinUI/UserControlBase.cs | New WinUI user control base integrating Stellar lifecycle. |
| Stellar.WinUI/Stellar.WinUI.csproj | New WinUI package/project targeting net10.0-windows with WindowsAppSDK + ReactiveUI.WinUI.Reactive. |
| Stellar.WinUI/PageBase.cs | New WinUI page base integrating Stellar lifecycle and navigation events. |
| Stellar.WinUI/HotReloadService.cs | New WinUI hot-reload metadata update handler + event dispatch. |
| Stellar.WinUI/GlobalUsings.cs | New WinUI project-wide usings for System.Reactive + ReactiveUI.Reactive. |
| Stellar.WinUI/Extensions/BuilderExtensions.cs | New WinUI DI extensions to initialize ReactiveUI services and enable hot reload. |
| Stellar.Uno/UserControlBase.cs | New Uno user control base implementing IViewFor + Stellar lifecycle hooks. |
| Stellar.Uno/UnoViewManager.cs | New Uno ViewManager with hot-reload binding re-registration. |
| Stellar.Uno/UnoScheduler.cs | New Uno UI-thread scheduler implementation (DispatcherQueue-backed). |
| Stellar.Uno/UnoActivationForViewFetcher.cs | New Uno activation fetcher enabling WhenActivated via Loaded/Unloaded. |
| Stellar.Uno/Stellar.Uno.csproj | New Uno package/project referencing Uno.WinUI + ReactiveUI.Reactive. |
| Stellar.Uno/PageBase.cs | New Uno page base implementing IViewFor + Stellar lifecycle + navigation. |
| Stellar.Uno/HotReloadService.cs | New Uno hot-reload metadata update handler + event dispatch. |
| Stellar.Uno/GlobalUsings.cs | New Uno project-wide usings for System.Reactive + ReactiveUI.Reactive. |
| Stellar.Uno/Extensions/BuilderExtensions.cs | New Uno DI extensions registering activation fetcher + main-thread scheduler; enable hot reload. |
| Stellar.UnitTests/Usings.cs | Add ReactiveUI.Reactive using for unit tests under ReactiveUI 24 split. |
| Stellar.MauiSample/Stellar.MauiSample.csproj | Switch MAUI sample to ReactiveUI.Maui.Reactive. |
| Stellar.MauiSample/GlobalUsings.cs | Add ReactiveUI.Reactive global using in MAUI sample. |
| Stellar.MauiBlazorHybridSample/GlobalUsings.cs | Add ReactiveUI.Reactive global using in hybrid sample. |
| Stellar.Maui/Views/ViewCellBase.cs | Add ReactiveUI.Maui.Views import to support new local ReactiveViewCell. |
| Stellar.Maui/Views/ReactiveViewCell.cs | Reintroduce ReactiveViewCell removed from ReactiveUI 24, preserving legacy API. |
| Stellar.Maui/Stellar.Maui.csproj | Switch MAUI library to ReactiveUI.Maui.Reactive. |
| Stellar.Maui/GlobalUsings.cs | Update MAUI global usings to include ReactiveUI.Reactive + ReactiveUI.Reactive.Maui and comment on namespace compatibility. |
| Stellar.Maui/Extensions/VisualElementExtensions.cs | Remove DynamicData.Diagnostics using. |
| Stellar.Maui/Extensions/MauiAppBuilderExtensions.cs | Update ReactiveUI builder usings to ReactiveUI.Reactive.* equivalents. |
| Stellar.Maui.PopUp/Stellar.Maui.PopUp.csproj | Switch popup project from ReactiveUI to ReactiveUI.Reactive. |
| Stellar.Maui.PopUp/ReactivePopupPage.cs | Add ReactiveUI.Reactive using for popup page. |
| Stellar.Maui.PopUp/Extensions/PopupNavigationObservableExtensions.cs | Add ReactiveUI.Reactive using for popup navigation extensions. |
| Stellar.BlazorSample/GlobalUsings.cs | Add ReactiveUI.Reactive global using in Blazor sample. |
| Stellar.Blazor/Stellar.Blazor.csproj | Switch Blazor integration to ReactiveUI.Blazor.Reactive. |
| Stellar.Blazor/LayoutComponentBase.cs | Update component base import to ReactiveUI.Reactive.Blazor. |
| Stellar.Blazor/InjectableComponentBase.cs | Update injectable component base import to ReactiveUI.Reactive.Blazor. |
| Stellar.Blazor/GlobalUsings.cs | Update Blazor global usings to ReactiveUI.Reactive + ReactiveUI.Reactive.Blazor. |
| Stellar.Blazor/Extensions/BuilderExtensions.cs | Update builder import to ReactiveUI.Reactive.Builder. |
| Stellar.Blazor/ComponentBase.cs | Update component base import to ReactiveUI.Reactive.Blazor. |
| Stellar.AvaloniaSample/Stellar.AvaloniaSample.csproj | Remove Avalonia.ReactiveUI and Avalonia.Diagnostics references. |
| Stellar.AvaloniaSample/Program.cs | Remove UseReactiveUI and rely on UseStellarComponents for ReactiveUI registrations. |
| Stellar.AvaloniaSample/GlobalUsings.cs | Add ReactiveUI.Reactive global using in Avalonia sample. |
| Stellar.Avalonia/WindowBase.cs | Replace ReactiveWindow dependency with direct Window + IViewFor implementation and VM/DataContext sync. |
| Stellar.Avalonia/UserControlBase.cs | Replace ReactiveUserControl dependency with direct UserControl + IViewFor implementation and VM/DataContext sync. |
| Stellar.Avalonia/Stellar.Avalonia.csproj | Remove Avalonia.ReactiveUI and Avalonia.Diagnostics references. |
| Stellar.Avalonia/Extensions/AppBuilderExtensions.cs | Replace Avalonia.ReactiveUI bootstrap with RxAppBuilder registrations using ReactiveUI.Reactive.Builder. |
| Stellar.Avalonia/AvaloniaScheduler.cs | New in-repo Avalonia UI-thread scheduler replacing Avalonia.ReactiveUI’s scheduler. |
| Stellar.Avalonia/AvaloniaActivationForViewFetcher.cs | New in-repo activation fetcher replacing Avalonia.ReactiveUI’s fetcher. |
| Directory.Packages.props | Central package version updates for ReactiveUI 24 split, Avalonia 12, CommunityToolkit updates, Windows/Uno dependencies. |
| .github/workflows/nuget.yml | Add WPF/WinUI/Uno packaging steps and notes for cross-compilation on non-Windows runners. |
Suppressed comments (8)
Stellar.Wpf/WpfViewManager.cs:1
- HandleHotReload checks
_viewbefore marshaling to the UI thread, but_viewcan become null between that check and the Dispatcher invocation (e.g., deactivation on the UI thread while a background thread is waiting). Capture_viewinto a local variable and use that inside the Invoke (or re-check inside the invoked delegate), similar to the WinUI/Uno implementations.
Stellar.Wpf/WindowBase.cs:1 - OnClosing can be canceled (e.Cancel = true) by derived classes/handlers. Calling
IsDisappearingandHandleDeactivatedbefore the close is confirmed can leave the window deactivated/disappearing even though it remains open. Consider callingbase.OnClosing(e)first and only deactivating when!e.Cancel, or move the deactivation path toOnClosedso it only runs when the window actually closes.
Stellar.WinUI/UserControlBase.cs:1 - The token from
RegisterPropertyChangedCallbackis not stored or unregistered. In WinUI, failing to callUnregisterPropertyChangedCallbackcan keep callbacks alive longer than intended and contribute to memory leaks. Store the returned token and unregister it (e.g., on Unloaded/Dispose) when the control is no longer needed.
Stellar.WinUI/PageBase.cs:1 - Same issue as in
UserControlBase: theRegisterPropertyChangedCallbacktoken is not unregistered, which can cause lifecycle/memory issues for pages that are navigated away from and later collected. Store the token and callUnregisterPropertyChangedCallbackat an appropriate lifecycle point.
Stellar.Uno/UserControlBase.cs:1 - The callback registration token is not kept/unregistered. Uno's WinUI API surface mirrors WinUI here, and leaving property-change callbacks registered can prolong object lifetimes. Store the token and unregister it when the view is unloaded/disposed.
Stellar.Uno/PageBase.cs:1 - As with the Uno UserControlBase/WinUI bases, the property changed callback is registered without ever being unregistered. Keep the returned token and unregister it at an appropriate point (e.g., Unloaded) to avoid leaking page instances.
Stellar.Uno/UnoScheduler.cs:1 DispatcherQueue.TryEnqueuereturns a boolean that indicates whether the work was actually enqueued. Ignoring the result can lead to silently dropped scheduled work (e.g., during shutdown), while the returnedIDisposablesuggests the action will run. Consider handling afalsereturn (e.g., dispose the inner disposable immediately, or surface an error/alternative behavior) so failures are not silent.
Stellar.Wpf/HotReloadService.cs:1- Suppressing CS8632 at the file level can mask real nullable-annotations configuration issues. Since the project sets
<Nullable>enable</Nullable>, it’s better to remove the suppression and ensure nullable is enabled for this file (e.g., via#nullable enableif needed) rather than disabling the warning; the same applies to the WinUI/Uno HotReloadService files.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Major-version migration plus three new platform packages, targeting v2.0.0.
ReactiveUI 23.2.28 → 24.0.0 (
.Reactivedistribution)ReactiveUI 24 re-platformed onto the new
ReactiveUI.Primitivesengine and split into two package families. Stellar adopts the.Reactivefamily (ReactiveUI.Reactive,ReactiveUI.Maui.Reactive,ReactiveUI.Blazor.Reactive):WhenAnyValue/ToPropertyper upstream benchmarks) — both distributions run on Primitives.Unit,IScheduler,Subject<T>) that Stellar's public API is built on; the default family would have changed them toRxVoid/ISequencer/Signal<T>across the entire API surface.System.Reactive7.0.0 is now a direct dependency (no longer flows transitively).Consumer impact: consumers add
global using ReactiveUI.Reactive;. That one line also fixes code emitted by ReactiveGenerator / ReactiveUI.SourceGenerators, which still generate 23-eraRaiseAndSetIfChangedcalls againstusing ReactiveUI;(global usings apply to generated files).Avalonia 11.3.18 → 12.1.1, Avalonia.ReactiveUI removed
Avalonia.ReactiveUI has no release compatible with ReactiveUI 24 (or Avalonia 12), so the dependency is gone. Stellar.Avalonia now owns the pieces it used:
WindowBase/UserControlBaseimplementIViewFordirectly, plus its ownAvaloniaSchedulerandAvaloniaActivationForViewFetcher. Removing the dependency is what unlocked Avalonia 12.Avalonia.Diagnosticsdropped (discontinued after 11.3; was referenced but unused).New platform heads: StellarUI.Wpf, StellarUI.WinUI, StellarUI.Uno
Mirror the existing per-platform pattern (ViewManager + base classes + builder extensions):
ReactiveUI.WPF.Reactive. Targetsnet10.0-windows10.0.19041.0; the plainnet10.0-windowsTFM silently resolves the package's .NET Framework assets (NU1701).ReactiveUI.WinUI.Reactive+ WindowsAppSDK 2.3.1; PRI/MSIX tooling disabled on non-Windows hosts so it cross-compiles on the mac/linux runners.All three are wired into
Stellar.sln,Stellar.slnf(so the ubuntu CI job builds them), and thenuget.ymlrelease matrix — which previously would have silently skipped them on av*tag.Other upgrades
.Reactive)Everything else already latest stable. Deliberate pins kept:
Microsoft.CodeAnalysis.CSharp5.0.0 (SDK feature-band loading), stylecop beta. ReactiveUI 24 also droppedReactiveViewCell; Stellar.Maui ships its own now.Validation
Stellar.slnfon macOS and in a Linuxdotnet/sdk:10.0container (ubuntu CI parity)Stellar.Maui+Stellar.Maui.PopUpRelease builds fornet10.0-androidandnet10.0-iosCompile-verified only (no local workload/runner): maccatalyst TFMs and Windows runtime behavior of the WPF/WinUI heads. Worth a
windows-latestCI job before tagging v2.0.0.🤖 Generated with Claude Code