ReactiveUI.SourceGenerators
1.1.26
Prefix Reserved
See the version list below for details.
dotnet add package ReactiveUI.SourceGenerators --version 1.1.26
NuGet\Install-Package ReactiveUI.SourceGenerators -Version 1.1.26
<PackageReference Include="ReactiveUI.SourceGenerators" Version="1.1.26" />
<PackageVersion Include="ReactiveUI.SourceGenerators" Version="1.1.26" />
<PackageReference Include="ReactiveUI.SourceGenerators" />
paket add ReactiveUI.SourceGenerators --version 1.1.26
#r "nuget: ReactiveUI.SourceGenerators, 1.1.26"
#:package ReactiveUI.SourceGenerators@1.1.26
#addin nuget:?package=ReactiveUI.SourceGenerators&version=1.1.26
#tool nuget:?package=ReactiveUI.SourceGenerators&version=1.1.26
ReactiveUI.SourceGenerators
Use source generators to generate ReactiveUI objects.
These Source Generators were designed to work in full with ReactiveUI V19.5.31 and newer supporting all features, currently:
- [Reactive]
- [ObservableAsProperty]
- [ObservableAsProperty(PropertyName = "ReadOnlyPropertyName")]
- [ReactiveCommand]
- [ReactiveCommand(CanExecute = nameof(IObservableBoolName))] with CanExecute
- [ReactiveCommand][property: AttribueToAddToCommand] with Attribute passthrough
- [IViewFor(nameof(ViewModelName))]
Versions older than V19.5.31 to this:
- [Reactive] fully supported,
- [ObservableAsProperty] fully supported,
- [ReactiveCommand] all options supported except Cancellation Token asnyc methods.
Historical ways
Read-write properties
Typically properties are declared like this:
private string _name;
public string Name
{
get => _name;
set => this.RaiseAndSetIfChanged(ref _name, value);
}
Before these Source Generators were avaliable we used ReactiveUI.Fody.
With ReactiveUI.Fody the [Reactive] Attribute was placed on a Public Property with Auto get / set properties, the generated code from the Source Generator and the Injected code using Fody are very similar with the exception of the Attributes.
[Reactive]
public string Name { get; set; }
ObservableAsPropertyHelper properties
Similarly, to declare output properties, the code looks like this:
public partial class MyReactiveClass : ReactiveObject
{
ObservableAsPropertyHelper<string> _firstName;
public MyReactiveClass()
{
_firstName = firstNameObservable
.ToProperty(this, x => x.FirstName);
}
public string FirstName => _firstName.Value;
private IObservable<string> firstNameObservable() => Observable.Return("Test");
}
With ReactiveUI.Fody, you can simply declare a read-only property using the [ObservableAsProperty] attribute, using either option of the two options shown below.
[ObservableAsProperty]
public string FirstName { get; }
Welcome to a new way - Source Generators
Usage Reactive property [Reactive]
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass : ReactiveObject
{
[Reactive]
private string _myProperty;
}
Usage ObservableAsPropertyHelper [ObservableAsProperty]
Usage ObservableAsPropertyHelper with Field
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass : ReactiveObject
{
[ObservableAsProperty]
private string _myProperty = "Default Value";
public MyReactiveClass()
{
_myPrpertyHelper = MyPropertyObservable()
.ToProperty(this, x => x.MyProperty);
}
IObservable<string> MyPropertyObservable() => Observable.Return("Test Value");
}
Usage ObservableAsPropertyHelper with Observable Property
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass : ReactiveObject
{
public MyReactiveClass()
{
// Initialize generated _myObservablePropertyHelper
// for the generated MyObservableProperty
InitializeOAPH();
}
[ObservableAsProperty]
IObservable<string> MyObservable => Observable.Return("Test Value");
}
Usage ObservableAsPropertyHelper with Observable Property and specific PropertyName
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass : ReactiveObject
{
public MyReactiveClass()
{
// Initialize generated _testValuePropertyHelper
// for the generated TestValueProperty
InitializeOAPH();
}
[ObservableAsProperty(PropertyName = TestValueProperty)]
IObservable<string> MyObservable => Observable.Return("Test Value");
}
Usage ObservableAsPropertyHelper with Observable Method
NOTE: This does not support methods with parameters
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass : ReactiveObject
{
public MyReactiveClass()
{
// Initialize generated _myObservablePropertyHelper
// for the generated MyObservableProperty
InitializeOAPH();
}
[ObservableAsProperty]
IObservable<string> MyObservable() => Observable.Return("Test Value");
}
Usage ObservableAsPropertyHelper with Observable Method and specific PropertyName
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass : ReactiveObject
{
public MyReactiveClass()
{
// Initialize generated _testValuePropertyHelper
// for the generated TestValueProperty
InitializeOAPH();
}
[ObservableAsProperty(PropertyName = TestValueProperty)]
IObservable<string> MyObservable() => Observable.Return("Test Value");
}
Usage ReactiveCommand [ReactiveCommand]
Usage ReactiveCommand without parameter
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass
{
public MyReactiveClass()
{
InitializeCommands();
}
[ReactiveCommand]
private void Execute() { }
}
Usage ReactiveCommand with parameter
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass
{
public MyReactiveClass()
{
InitializeCommands();
}
[ReactiveCommand]
private void Execute(string parameter) { }
}
Usage ReactiveCommand with parameter and return value
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass
{
public MyReactiveClass()
{
InitializeCommands();
}
[ReactiveCommand]
private string Execute(string parameter) => parameter;
}
Usage ReactiveCommand with parameter and async return value
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass
{
public MyReactiveClass()
{
InitializeCommands();
}
[ReactiveCommand]
private async Task<string> Execute(string parameter) => await Task.FromResult(parameter);
}
Usage ReactiveCommand with IObservable return value
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass
{
public MyReactiveClass()
{
InitializeCommands();
}
[ReactiveCommand]
private IObservable<string> Execute(string parameter) => Observable.Return(parameter);
}
Usage ReactiveCommand with CancellationToken
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass
{
public MyReactiveClass()
{
InitializeCommands();
}
[ReactiveCommand]
private async Task Execute(CancellationToken token) => await Task.Delay(1000, token);
}
Usage ReactiveCommand with CancellationToken and parameter
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass
{
public MyReactiveClass()
{
InitializeCommands();
}
[ReactiveCommand]
private async Task<string> Execute(string parameter, CancellationToken token)
{
await Task.Delay(1000, token);
return parameter;
}
}
Usage ReactiveCommand with CanExecute
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass
{
private IObservable<bool> _canExecute;
[Reactive]
private string _myProperty1;
[Reactive]
private string _myProperty2;
public MyReactiveClass()
{
InitializeCommands();
_canExecute = this.WhenAnyValue(x => x.MyProperty1, x => x.MyProperty2, (x, y) => !string.IsNullOrEmpty(x) && !string.IsNullOrEmpty(y));
}
[ReactiveCommand(CanExecute = nameof(_canExecute))]
private void Search() { }
}
Usage ReactiveCommand with property Attribute pass through
using ReactiveUI.SourceGenerators;
public partial class MyReactiveClass
{
private IObservable<bool> _canExecute;
[Reactive]
private string _myProperty1;
[Reactive]
private string _myProperty2;
public MyReactiveClass()
{
InitializeCommands();
_canExecute = this.WhenAnyValue(x => x.MyProperty1, x => x.MyProperty2, (x, y) => !string.IsNullOrEmpty(x) && !string.IsNullOrEmpty(y));
}
[ReactiveCommand(CanExecute = nameof(_canExecute))]
[property: JsonIgnore]
private void Search() { }
}
Usage IViewFor [IViewFor(nameof(ViewModelName))]
IViewFor usage
IVIewFor is used to link a View to a ViewModel, this is used to link the ViewModel to the View in a way that ReactiveUI can use it to bind the ViewModel to the View. The ViewModel is passed as a string to the IViewFor Attribute. The class must inherit from a UI Control from any of the following platforms and namespaces:
- Maui (Microsoft.Maui)
- WinUI (Microsoft.UI.Xaml)
- WPF (System.Windows or System.Windows.Controls)
- WinForms (System.Windows.Forms)
- Avalonia (Avalonia)
- Uno (Windows.UI.Xaml).
using ReactiveUI.SourceGenerators;
[IViewFor(nameof(MyReactiveClass))]
public partial class MyReactiveControl : UserControl
{
public MyReactiveControl()
{
InitializeComponent();
MyReactiveClass = new MyReactiveClass();
}
}
Platform specific Attributes
WinForms
RoutedControlHost
using ReactiveUI.SourceGenerators.WinForms;
[RoutedControlHost("YourNameSpace.CustomControl")]
public partial class MyCustomRoutedControlHost;
ViewModelControlHost
using ReactiveUI.SourceGenerators.WinForms;
[ViewModelControlHost("YourNameSpace.CustomControl")]
public partial class MyCustomViewModelControlHost;
TODO:
- Add ObservableAsProperty to generate from a IObservable method with parameters.
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.Analyzers (>= 3.3.4)
- Microsoft.CodeAnalysis.CSharp (>= 4.0.1)
- Microsoft.CodeAnalysis.CSharp.Workspaces (>= 4.0.1)
NuGet packages (7)
Showing the top 5 NuGet packages that depend on ReactiveUI.SourceGenerators:
| Package | Downloads |
|---|---|
|
Zafiro.Avalonia.Dialogs
UI components, controls, dialogs, behaviors, and helpers for Avalonia applications. Includes reactive patterns, cross-platform support (desktop, mobile, browser), and source generators. |
|
|
SuppaWallet.Gui.Model.Impl
Package Description |
|
|
SuppaWallet.Gui
Package Description |
|
|
SuppaWallet.Infrastructure.Default
Package Description |
|
|
Helium.Visible
Package Description |
GitHub repositories (15)
Showing the top 15 popular GitHub repositories that depend on ReactiveUI.SourceGenerators:
| Repository | Stars |
|---|---|
|
gui-cs/Terminal.Gui
Cross Platform Terminal UI toolkit for .NET
|
|
|
timschneeb/GalaxyBudsClient
Unofficial Galaxy Buds Manager for Windows, macOS, Linux, and Android
|
|
|
HMBSbige/NatTypeTester
测试当前网络的 NAT 类型(STUN)
|
|
|
reactiveui/Akavache
An asynchronous, persistent key-value store created for writing desktop and mobile applications, based on SQLite3. Akavache is great for both storing important data as well as cached local data that expires.
|
|
|
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
|
|
|
AvaloniaUI/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
Validation helpers for ReactiveUI-based apps.
|
|
|
mysteryx93/HanumanInstitute.MvvmDialogs
Library simplifying the concept of opening dialogs from a view model when using MVVM
|
|
|
reactiveui/ReactiveMvvm
Cross-platform ReactiveUI sample app built for a talk at MSK .NET conf.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 2.6.30 | 1,410 | 4/26/2026 |
| 2.6.1 | 52,627 | 1/12/2026 |
| 2.5.1 | 26,631 | 10/24/2025 |
| 2.4.1 | 15,088 | 9/2/2025 |
| 2.3.1 | 15,444 | 6/29/2025 |
| 2.2.4 | 8,457 | 6/1/2025 |
| 2.1.27 | 15,826 | 3/16/2025 |
| 2.1.8 | 56,243 | 2/13/2025 |
| 2.1.1 | 1,834 | 1/29/2025 |
| 2.0.17 | 7,865 | 11/9/2024 |
| 1.1.31 | 3,600 | 9/19/2024 |
| 1.1.26 | 416 | 9/16/2024 |
| 1.0.3 | 20,234 | 7/19/2024 |
| 1.0.2 | 501 | 7/18/2024 |