feat!: bring ReactiveUI.SourceGenerators with ReactiveUI.Core by glennawatson · Pull Request #4516 · reactiveui/ReactiveUI · GitHub
Skip to content

feat!: bring ReactiveUI.SourceGenerators with ReactiveUI.Core - #4516

Merged
glennawatson merged 1 commit into
mainfrom
feat/sourcegenerators-dependency
Sep 26, 2026
Merged

glennawatson merged 1 commit into
mainfrom
feat/sourcegenerators-dependency

Conversation

@glennawatson

Copy link
Copy Markdown
Contributor

Summary

Every ReactiveUI project now gets the ReactiveUI.SourceGenerators generators, brought in through ReactiveUI.Core.

  • ReactiveUI.Core references ReactiveUI.SourceGenerators 4.0.0 with PrivateAssets="none". ReactiveUI and ReactiveUI.Reactive both depend on Core, so [Reactive], [ReactiveCommand], [ReactiveCollection], [BindableDerivedList] and [IReactiveObject] work in either flavour with no extra package.
  • The generators write code for the flavour the project references. A ReactiveUI.Reactive project gets ReactiveUI.Reactive.ReactiveCommand<Unit, T>; a ReactiveUI project gets ReactiveUI.ReactiveCommand<RxVoid, T>.
  • New integration tests use the attributes in the shared test source. They run in ReactiveUI.Tests and ReactiveUI.Tests.Reactive, alongside ReactiveUI.Binding's WhenAnyValue and [ObservableAsProperty].
  • The README explains the package layout as it is now. It opens with a view model built from the generators, then covers the two flavours, ReactiveUI.Core bringing the source generators, ReactiveUI.Binding bringing bindings, analyzers, routing and the platform packages.
  • Rodney Littles II and Colt Bauman move to the alumni team in the README.

Why

Source generators are the recommended way to write ReactiveUI view models, so they should arrive with ReactiveUI rather than as a separate install. ReactiveUI already brings ReactiveUI.Binding the same way.

Breaking changes

The ReactiveUI.SourceGenerators generators and analyzers now run in every project that references ReactiveUI or ReactiveUI.Reactive.

  • A project that references an older ReactiveUI.SourceGenerators itself fails to restore with NU1605. Remove that reference, or move it to 4.0.0 or later.
  • ReactiveUI.SourceGenerators 4.0.0 leaves [ObservableAsProperty] and [IViewFor] to ReactiveUI.Binding. Code written against the 3.x attributes follows the ReactiveUI.SourceGenerators 4.0.0 release notes.

How this was verified

The new tests cover generated properties and commands in both flavours. Scratch console apps against packed ReactiveUI and ReactiveUI.Reactive packages exercised every attribute, the README example and a NativeAOT publish. A Windows Forms app checked that the generator's host attributes compile next to ReactiveUI.Winforms' own RoutedControlHost and ViewModelControlHost controls.

Notes for the reviewer

The code change is two lines of MSBuild; the rest is tests and README.

  • The reference sits on ReactiveUI.Core, not on the two leaves. The leaves reach Core through a project reference, and NuGet still passes the generator on through the packed dependency.
  • WhenAnyValue cannot observe a property the generators write from a [Reactive] field. ReactiveUI.Binding's generator cannot see that property, so the call throws at run time. The README tells readers to use the partial-property form; the fix belongs in ReactiveUI.Binding.
  • The Windows Forms [RoutedControlHost] and [ViewModelControlHost] hosts from ReactiveUI.SourceGenerators 4.0.0 throw when constructed. Their generated constructor calls WhenAny, and ReactiveUI.Binding writes no dispatch for a call inside another generator's output. This already affects anyone using those attributes with ReactiveUI 24; the fix belongs in ReactiveUI.SourceGenerators, so the README does not advertise them.

Checklist

  • I have read the Contribute guide
  • The PR title follows Conventional Commits
  • Tests cover this change, or the summary says why they do not
  • New or changed public API has XML documentation

ReactiveUI.Core now references ReactiveUI.SourceGenerators 4.0.0 with
PrivateAssets="none". ReactiveUI and ReactiveUI.Reactive both build on
Core, so every consumer of either flavour gets the [Reactive],
[ReactiveCommand], [ReactiveCollection], [BindableDerivedList] and
[IReactiveObject] generators without installing the package. The
generators detect the flavour the consumer references and write code
against it.

New integration tests use the attributes in the shared test source, so
ReactiveUI.Tests and ReactiveUI.Tests.Reactive check the generated
properties and commands against both flavours, together with
ReactiveUI.Binding's WhenAnyValue and [ObservableAsProperty].

The README explains the package layout: the two flavours, ReactiveUI.Core
bringing the source generators, ReactiveUI.Binding bringing bindings,
and the platform packages. It opens with a view model built from the
generators. Rodney Littles II and Colt Bauman move to the alumni team.

BREAKING CHANGE: The ReactiveUI.SourceGenerators generators and
analyzers now run in every project that references ReactiveUI or
ReactiveUI.Reactive. A project that references an older
ReactiveUI.SourceGenerators itself fails to restore with NU1605; remove
that reference or move it to 4.0.0 or later.
@codecov

codecov Bot commented Sep 26, 2026

Copy link
Copy Markdown

@sonarqubecloud

Copy link
Copy Markdown

@glennawatson
glennawatson merged commit aba5bb2 into main Sep 26, 2026
14 of 17 checks passed
@glennawatson
glennawatson deleted the feat/sourcegenerators-dependency branch September 26, 2026 13:43
glennawatson added a commit that referenced this pull request Sep 26, 2026
## Summary

**ReactiveUI.Core now brings ReactiveUI.SourceGenerators 4.0.1.**

- **The WinForms `[RoutedControlHost]` and `[ViewModelControlHost]`
hosts work.** 4.0.1 stops the generated hosts from calling `WhenAny`,
which threw at construction because no generated binding dispatch
matched the call. Hosts declared in the global namespace, or nested in
another type, now get their members on the right type.

## Why

**4.0.0, which #4516 made a ReactiveUI.Core dependency, generated
WinForms hosts that threw when constructed.** Every ReactiveUI consumer
now gets the fixed generators.

## Breaking changes

**None.**

## How this was verified

**ReactiveUI.Core builds with warnings as errors, and the ReactiveUI
tests, including the source generator integration tests, pass against
4.0.1.**

## Notes for the reviewer

**One line in `src/Directory.Packages.props`.**

## Checklist
- [x] I have read the [Contribute
guide](https://www.reactiveui.net/contribute/index.html)
- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/)
- [x] Tests cover this change, or the summary says why they do not
- [ ] New or changed public API has XML documentation
@github-actions

Copy link
Copy Markdown

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Oct 10, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant