Skip to content

Migrate to ReactiveUI 24 (.Reactive), Avalonia 12, and add WPF / WinUI 3 / Uno platform heads - #36

Merged
michaelstonis merged 3 commits into
developfrom
feature/reactiveui-24-and-windows-platforms
Aug 6, 2026
Merged

michaelstonis merged 3 commits into
developfrom
feature/reactiveui-24-and-windows-platforms

Conversation

@michaelstonis

Copy link
Copy Markdown
Contributor

Summary

Major-version migration plus three new platform packages, targeting v2.0.0.

ReactiveUI 23.2.28 → 24.0.0 (.Reactive distribution)

ReactiveUI 24 re-platformed onto the new ReactiveUI.Primitives engine and split into two package families. Stellar adopts the .Reactive family (ReactiveUI.Reactive, ReactiveUI.Maui.Reactive, ReactiveUI.Blazor.Reactive):

  • Same engine and hot-path performance gains as the default packages (3–4× faster WhenAnyValue/ToProperty per upstream benchmarks) — both distributions run on Primitives.
  • Keeps the System.Reactive 7 types (Unit, IScheduler, Subject<T>) that Stellar's public API is built on; the default family would have changed them to RxVoid/ISequencer/Signal<T> across the entire API surface.
  • System.Reactive 7.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-era RaiseAndSetIfChanged calls against using 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/UserControlBase implement IViewFor directly, plus its own AvaloniaScheduler and AvaloniaActivationForViewFetcher. Removing the dependency is what unlocked Avalonia 12. Avalonia.Diagnostics dropped (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):

  • 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 (NU1701).
  • Stellar.WinUI — ReactiveUI.WinUI.Reactive + WindowsAppSDK 2.3.1; PRI/MSIX tooling disabled on non-Windows hosts so it cross-compiles on the mac/linux runners.
  • Stellar.Uno — Uno.WinUI 6.6.176; no ReactiveUI 24-compatible Uno package exists, so it hand-rolls activation fetcher + scheduler the same way Stellar.Avalonia does.

All three are wired into Stellar.sln, Stellar.slnf (so the ubuntu CI job builds them), and the nuget.yml release matrix — which previously would have silently skipped them on a v* tag.

Other upgrades

Package Before After
ReactiveUI / .Maui / .Blazor 23.2.28 24.0.0 (.Reactive)
Avalonia + companions 11.3.18 12.1.1
CommunityToolkit.Maui 14.2.2 15.0.0
CommunityToolkit.Maui.Markup 7.0.1 8.0.0
System.Reactive (transitive) 7.0.0 direct

Everything else already latest stable. Deliberate pins kept: Microsoft.CodeAnalysis.CSharp 5.0.0 (SDK feature-band loading), stylecop beta. ReactiveUI 24 also dropped ReactiveViewCell; Stellar.Maui ships its own now.

Validation

  • Release build of Stellar.slnf on macOS and in a Linux dotnet/sdk:10.0 container (ubuntu CI parity)
  • 259/259 unit tests pass (Release)
  • Pack rehearsal: all 9 non-MAUI release-matrix projects produce nupkgs
  • Stellar.Maui + Stellar.Maui.PopUp Release builds for net10.0-android and net10.0-ios
  • MauiSample / MauiBlazorHybridSample / AvaloniaSample / BlazorSample build

Compile-verified only (no local workload/runner): maccatalyst TFMs and Windows runtime behavior of the WPF/WinUI heads. Worth a windows-latest CI job before tagging v2.0.0.

🤖 Generated with Claude Code

github-actions Bot and others added 3 commits August 3, 2026 17:29
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…/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>
Copilot AI lite review requested due to automatic review settings August 6, 2026 15:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 _view before marshaling to the UI thread, but _view can become null between that check and the Dispatcher invocation (e.g., deactivation on the UI thread while a background thread is waiting). Capture _view into 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 IsDisappearing and HandleDeactivated before the close is confirmed can leave the window deactivated/disappearing even though it remains open. Consider calling base.OnClosing(e) first and only deactivating when !e.Cancel, or move the deactivation path to OnClosed so it only runs when the window actually closes.
    Stellar.WinUI/UserControlBase.cs:1
  • The token from RegisterPropertyChangedCallback is not stored or unregistered. In WinUI, failing to call UnregisterPropertyChangedCallback can 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: the RegisterPropertyChangedCallback token is not unregistered, which can cause lifecycle/memory issues for pages that are navigated away from and later collected. Store the token and call UnregisterPropertyChangedCallback at 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.TryEnqueue returns 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 returned IDisposable suggests the action will run. Consider handling a false return (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 enable if needed) rather than disabling the warning; the same applies to the WinUI/Uno HotReloadService files.

@michaelstonis
michaelstonis merged commit d4f3d97 into develop Aug 6, 2026
3 of 5 checks passed
@michaelstonis
michaelstonis deleted the feature/reactiveui-24-and-windows-platforms branch August 6, 2026 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants