ReactiveUI.SourceGenerators
5.0.0
Prefix Reserved
dotnet add package ReactiveUI.SourceGenerators --version 5.0.0
NuGet\Install-Package ReactiveUI.SourceGenerators -Version 5.0.0
<PackageReference Include="ReactiveUI.SourceGenerators" Version="5.0.0" />
<PackageVersion Include="ReactiveUI.SourceGenerators" Version="5.0.0" />
<PackageReference Include="ReactiveUI.SourceGenerators" />
paket add ReactiveUI.SourceGenerators --version 5.0.0
#r "nuget: ReactiveUI.SourceGenerators, 5.0.0"
#:package ReactiveUI.SourceGenerators@5.0.0
#addin nuget:?package=ReactiveUI.SourceGenerators&version=5.0.0
#tool nuget:?package=ReactiveUI.SourceGenerators&version=5.0.0
ReactiveUI.SourceGenerators
ReactiveUI.SourceGenerators writes ReactiveUI boilerplate for you when you build: reactive properties, commands,
IReactiveObject implementations, IViewFor<T> views, derived lists, reactive collections and WinForms control hosts.
The generated code uses no reflection, so it works with trimming and Native AOT.
The same repository also builds ReactiveUI.Binding,
which generates the code behind WhenAnyValue, Bind, BindCommand, ToProperty and [ObservableAsProperty].
The two packages work together and share their infrastructure.
- Minimum requirements
- C# 12.0
- Visual Studio 17.8 (Roslyn 4.8) or the .NET 8 SDK; partial properties need Visual Studio 17.14 or later
- ReactiveUI 23.2.28 or later
Table of contents
- Installation
- Overview
- Roslyn and Visual Studio support
- Migration from ReactiveUI.Fody
- Reactive properties
- Reactive commands
- Views
- Derived lists and collections
- WinForms control hosts
- Working with ReactiveUI.Binding
- Credits
Installation
dotnet add package ReactiveUI.SourceGenerators
Load the package with PrivateAssets="all" so the generator does not flow to projects that reference yours:
<PackageReference Include="ReactiveUI.SourceGenerators" Version="..." PrivateAssets="all" />
The attributes ([Reactive], [ReactiveCommand] and the rest) are public types in the package's
ReactiveUI.SourceGenerators assembly. The generators do not declare them in your project, so assemblies that share
internals through InternalsVisibleTo never see two copies. Your project compiles against that assembly but keeps no
reference to it. If an older install added an <IncludeAssets> line without compile, remove it.
ReactiveUI 24 consumers can reference either ReactiveUI, for the API without System.Reactive, or ReactiveUI.Reactive,
for the System.Reactive API. The generators detect the API you reference.
For .NET Framework 4.8 and older, add Polyfill or
PolySharp and set LangVersion to 12.0 or later.
Overview
| Attribute | What it generates |
|---|---|
[Reactive] |
A property with change notification, from a field or from a partial property |
[ReactiveCommand] |
A ReactiveCommand property for a method, with CanExecute, schedulers and background options |
[IReactiveObject] |
The IReactiveObject implementation, for classes that cannot derive from ReactiveObject |
[IViewFor], [IViewFor<T>] |
The ViewModel property and the IViewFor<T> implementation of a view |
[BindableDerivedList] |
A derived list for a ReadOnlyObservableCollection<T> field |
[ReactiveCollection] |
Change notifications for an ObservableCollection<T> field |
[RoutedControlHost], [ViewModelControlHost] |
WinForms hosts that show the view for a view model |
Roslyn and Visual Studio support
The package ships three analyzer bands. Your compiler picks the highest band at or below its own Roslyn version.
Band (analyzers/dotnet/...) |
Roslyn | Minimum tooling | Covers |
|---|---|---|---|
roslyn4.8 |
4.8 | Visual Studio 2022 17.8, .NET 8 SDK | The whole .NET 8 SDK line (Roslyn 4.8 to 4.11) and Visual Studio 17.12 and 17.13 |
roslyn4.14 |
4.14 | Visual Studio 2022 17.14, .NET 9 SDK | Partial-property [Reactive] |
roslyn5.0 |
5.0 | Visual Studio 2026, .NET 10 SDK | Partial-property [Reactive] |
The roslyn4.8 band compiles against the Roslyn 4.8 API only, so it loads on every .NET 8 SDK band without the
CS9057 error. See the
Roslyn package version mappings.
Migration from ReactiveUI.Fody
- Remove the ReactiveUI.Fody package,
FodyWeavers.xmlandFodyWeavers.xsd. - Add the ReactiveUI.SourceGenerators package.
- Declare your classes and properties
partial, put[Reactive]on them, and replace theReactiveUI.Fody.Helpersusing withReactiveUI.SourceGenerators.[Reactive]also works on a backing field. - Replace Fody's
[ObservableAsProperty]with ReactiveUI.Binding's. - Rebuild and check the generated code.
Reactive properties
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass : ReactiveObject
{
[Reactive]
private string _myProperty;
}
Options:
// Access modifier of the set accessor (not needed for a partial property: declare it on the property).
[Reactive(SetModifier = AccessModifier.Protected)]
private string _first;
// A virtual property.
[Reactive(Inheritance = InheritanceModifier.Virtual)]
private string _second;
// Also raise notifications for other properties.
[Reactive(nameof(Other1), nameof(Other2))]
private string _third;
// Pass an attribute to the generated property.
[Reactive]
[property: JsonIgnore]
private string _fourth;
From a partial property
Partial properties need C# 13 and Visual Studio 17.14 or later. Leave both accessors empty. virtual, override,
required and a private or protected set accessor are written on the property itself. C# 14 also allows an
initializer.
public partial class MyReactiveClass : ReactiveObject
{
[Reactive]
public partial string MyProperty { get; set; }
}
With other source generators
Roslyn does not order generators, and each one sees the original compilation. Code that one generator writes is
invisible to the others in the same project. For example, the System.Text.Json generator does not see a
[JsonPropertyName] that [Reactive] adds. To serialize [Reactive] properties with that generator, define the types
in assembly A and the JsonSerializerContext in assembly B, which references A.
Reactive commands
public partial class MyReactiveClass
{
[ReactiveCommand]
private void Execute() { } // ExecuteCommand
[ReactiveCommand]
private string Echo(string parameter) => parameter; // parameter and result
[ReactiveCommand]
private async Task<string> LoadAsync(string id) => await Task.FromResult(id); // LoadCommand: Async is dropped
[ReactiveCommand]
private IObservable<string> Watch(string id) => Observable.Return(id);
[ReactiveCommand]
private async Task Delay(CancellationToken token) => await Task.Delay(1000, token);
}
CanExecute
private IObservable<bool> _canSearch;
[ReactiveCommand(CanExecute = nameof(_canSearch))]
private void Search() { }
Schedulers and background work
RunInBackground runs a synchronous method on ReactiveUI's background scheduler. A task-returning method starts with
Task.Run, so the code before its first await leaves the calling thread. The command parameter and
CancellationToken are passed through. BackgroundScheduler chooses the scheduler a synchronous method runs on and
implies RunInBackground.
OutputScheduler and BackgroundScheduler name a scheduler as you would write it in the class: a field, property or
parameterless method of the class, or a static one elsewhere, such as RxSchedulers.MainThreadScheduler. A name that
does not resolve to a scheduler is reported as RXUISG0021.
[ReactiveCommand(RunInBackground = true)]
private void Crunch() { }
[ReactiveCommand(BackgroundScheduler = nameof(_workScheduler))]
private void CrunchOnMine() { }
[ReactiveCommand(OutputScheduler = "RxSchedulers.MainThreadScheduler")]
private void ShowResult() { }
[ReactiveCommand(AccessModifier = PropertyAccessModifier.Internal)]
private void Hidden() { }
[ReactiveCommand]
[property: JsonIgnore]
private void Save() { }
A [ReactiveCommand] method with more than one parameter besides a CancellationToken (RXUISG0002), an async void
method (RXUISG0008) and a scheduler name that does not resolve (RXUISG0021) are reported, because the generator skips
them.
Views
[IViewFor] makes a partial control implement IViewFor<TViewModel>. It writes the ViewModel property and the
interface members, and registers the view with ReactiveUI.Binding's view locator at compile time.
using ReactiveUI.SourceGenerators;
[IViewFor<LoginViewModel>]
public partial class LoginView : UserControl
{
}
// The view model by name, when its type is not in scope or is generic.
[IViewFor("Contracts.LoginViewModel")]
public partial class OtherView : UserControl
{
}
Derived lists and collections
public partial class MyReactiveClass : ReactiveObject
{
// A ReadOnlyObservableCollection<string> property bound to a source list.
[BindableDerivedList]
private readonly ReadOnlyObservableCollection<string> _myList;
// Change notifications on add, remove and replace.
[ReactiveCollection]
private ObservableCollection<string> _myCollection;
}
IReactiveObject for classes that cannot derive from ReactiveObject
[IReactiveObject]
public partial class MyReactiveClass
{
[Reactive]
private string _myProperty;
}
WinForms control hosts
using ReactiveUI.SourceGenerators.WinForms;
[RoutedControlHost("YourNameSpace.CustomControl")]
public partial class MyCustomRoutedControlHost;
[ViewModelControlHost("YourNameSpace.CustomControl")]
public partial class MyCustomViewModelControlHost;
Both resolve views through ReactiveUI's view locator, or through ReactiveUI.Binding's when your ReactiveUI is built on
it. With ReactiveUI.Binding 8.4.0 or later they follow their own properties through Binding's ObservedProperty.
Working with ReactiveUI.Binding
ReactiveUI.Binding generates the code behind [ObservableAsProperty] and view registration. Use it for both.
A read-only property backed by an observable
Mark a partial property [ObservableAsProperty] (C# 13 or later). The generator writes the property body and a helper
field named after it, which you assign with ToProperty:
using ReactiveUI;
using ReactiveUI.Binding;
public partial class MyReactiveClass : ReactiveObject
{
public MyReactiveClass(IObservable<string> source) =>
_myPropertyHelper = source.ToProperty(this, x => x.MyProperty, initialValue: "Default Value");
[ObservableAsProperty]
public partial string MyProperty { get; }
}
ReactiveUI.Binding needs a ReactiveUI release built on it. On ReactiveUI 24.3 and earlier, write the helper by hand:
private readonly ObservableAsPropertyHelper<string> _myPropertyHelper;
public string MyProperty => _myPropertyHelper.Value;
Generated code and intercepted calls
One generator cannot see another generator's output. The attribute generators therefore never write a call that
ReactiveUI.Binding has to intercept (WhenAny*, Bind, OneWayBind, BindCommand). Generated code that follows a
property uses Binding's ObservedProperty when it is available, and PropertyChanged otherwise.
Credits
Portions of this code base are based on and derived from
- PolySharp library. Thanks go to @Sergio0694
- Microsoft MVVM Community Toolkit
See our sponsors for the people and companies that support the project.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. net11.0 is compatible. |
| .NET Framework | net47 is compatible. net471 is compatible. net472 is compatible. net48 is compatible. net481 is compatible. |
-
.NETFramework 4.7
- No dependencies.
-
.NETFramework 4.7.1
- No dependencies.
-
.NETFramework 4.7.2
- No dependencies.
-
.NETFramework 4.8
- No dependencies.
-
.NETFramework 4.8.1
- No dependencies.
-
net10.0
- No dependencies.
-
net11.0
- No dependencies.
NuGet packages (49)
Showing the top 5 NuGet packages that depend on ReactiveUI.SourceGenerators:
| Package | Downloads |
|---|---|
|
ReactiveUI
A MVVM framework that integrates with the Reactive Extensions for .NET to create elegant, testable User Interfaces that run on any mobile or desktop platform. This is the base package with the base platform implementations |
|
|
ReactiveUI.WPF
Contains the ReactiveUI platform specific extensions for Windows Presentation Foundation (WPF) |
|
|
ReactiveUI.Testing
Provides extensions for testing ReactiveUI based applications |
|
|
ReactiveUI.Blazor
Contains the ReactiveUI platform specific extensions for Blazor |
|
|
ReactiveUI.Maui
Contains the ReactiveUI platform specific extensions for Microsoft Maui |
GitHub repositories (15)
Showing the top 15 popular GitHub repositories that depend on ReactiveUI.SourceGenerators:
| Repository | Stars |
|---|---|
|
timschneeb/GalaxyBudsClient
Unofficial Galaxy Buds Manager for Windows, macOS, Linux, and Android
|
|
|
HMBSbige/NatTypeTester
测试当前网络的 NAT 类型(STUN)
|
|
|
reactiveui/Akavache
An asynchronous, persistent key-value store for .NET desktop and mobile applications, backed by SQLite. Suited to both durable data such as user settings and cached data that expires, with optional encryption and System.Text.Json serialization.
|
|
|
TEdit/Terraria-Map-Editor
TEdit - Terraria Map Editor - TEdit is a stand alone, open source map editor for Terraria. It lets you edit maps just like (almost) paint! It also lets you change world settings (time, bosses downed etc), edit chests and change sign, make epic dungeons, castles, cities, and add rewards for your adventurers!
|
|
|
wieslawsoltes/Dock
A docking layout system.
|
|
|
database64128/youtube-dl-wpf
WPF GUI for youtube-dl and yt-dlp.
|
|
|
LibUsbDotNet/LibUsbDotNet
My updates to LibUsbDotNet, an excellent library for cross-platform USB device control using Mono/.NET
|
|
|
PhantomGamers/SFP
This utility is designed to allow you to apply skins to the modern Steam client
|
|
|
AvaloniaCommunity/Avalonia.Markup.Declarative
Provides helpers for declarative ui in C#
|
|
|
Monitor221hz/Pandora-Behaviour-Engine-Plus
Patcher for behavior, character, and skeleton project files for Skyrim Special Edition.
|
|
|
OpenHarmony-NET/OpenHarmony.Avalonia
|
|
|
reactiveui/ReactiveUI.Validation
Reactive validation for ReactiveUI view models. Declare validation rules as observables over properties and bind the results to views on any supported .NET platform.
|
|
|
mysteryx93/HanumanInstitute.MvvmDialogs
Library simplifying the concept of opening dialogs from a view model when using MVVM
|
|
|
reactiveui/ReactiveMvvm
A sample application showing one set of ReactiveUI view models shared across many .NET UI frameworks. Includes front ends for Avalonia, .NET MAUI, WPF, Windows Forms, Blazor and Terminal.Gui.
|
|
|
mcodersir/dicodePing
A VPN client that offers free servers and one-click connection.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 5.0.0 | 0 | 11/15/2026 |
| 4.2.0 | 168,382 | 9/26/2026 |
| 4.1.0 | 732 | 9/26/2026 |
| 4.0.1 | 721 | 9/26/2026 |
| 4.0.0 | 856 | 9/26/2026 |
| 3.2.0 | 118,537 | 8/1/2026 |
| 3.1.0 | 75,000 | 6/4/2026 |
| 3.0.0 | 2,414 | 6/3/2026 |
| 2.6.1 | 99,511 | 1/12/2026 |
| 2.5.1 | 43,159 | 10/24/2025 |
| 2.4.1 | 19,867 | 9/2/2025 |
| 2.3.1 | 19,087 | 6/29/2025 |
| 2.2.4 | 9,924 | 6/1/2025 |
| 2.1.27 | 17,994 | 3/16/2025 |
| 2.1.8 | 61,051 | 2/13/2025 |
| 2.1.1 | 2,425 | 1/29/2025 |
| 2.0.17 | 9,457 | 11/9/2024 |
| 1.1.31 | 4,197 | 9/19/2024 |