MvvmAIO.R3.SourceGenerators
0.6.1
dotnet add package MvvmAIO.R3.SourceGenerators --version 0.6.1
NuGet\Install-Package MvvmAIO.R3.SourceGenerators -Version 0.6.1
<PackageReference Include="MvvmAIO.R3.SourceGenerators" Version="0.6.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="MvvmAIO.R3.SourceGenerators" Version="0.6.1" />
<PackageReference Include="MvvmAIO.R3.SourceGenerators"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add MvvmAIO.R3.SourceGenerators --version 0.6.1
#r "nuget: MvvmAIO.R3.SourceGenerators, 0.6.1"
#:package MvvmAIO.R3.SourceGenerators@0.6.1
#addin nuget:?package=MvvmAIO.R3.SourceGenerators&version=0.6.1
#tool nuget:?package=MvvmAIO.R3.SourceGenerators&version=0.6.1
MvvmAIO.R3.SourceGenerators
Roslyn source generators for R3-based MVVM workflows.
Stability
This project is in an early stage. Until 1.0.0 is published, breaking changes may occur without a long deprecation window (API surface, generated code shape, namespaces, and package layout can all change). When upgrading, review CHANGELOG.md or GitHub releases.
Features
- Observable events —
FromEvents(),FromEventHandlers(), and routedFromRoutedEvents()/FromRoutedEventHandlers()(WPF whenUseWPFis true; Avalonia whenRoutedEvent<T>metadata is present). Entry extensions live inR3.SourceGenerators; streams useR3.Observablefrom R3. Per-event surfaces are properties on generated internal interfaces (ReactiveMarbles-style chaining). - Interface-based codegen — event interfaces (e.g.
IButtonEvents,IButtonRoutedEvents) andsealedimplementations mirror the source type hierarchy. See docs/design-interface-based-event-generation.md. - Generic constraints —
source.FromEvents()insidewhere T : Base, I1, I2resolves to a combined interface inheriting all constraint event interfaces. [R3Command](MvvmAIO.R3) — generatesReactiveCommandproperties on partial types, with optionalCanExecuteandCommandName.- Multi-Roslyn — analyzer builds for Roslyn 4.3 / 4.12 / 5.x; MSBuild selects the matching folder under
analyzers/dotnet/. - NRT — generated code preserves nullable annotations from original event signatures.
Installation
dotnet add package MvvmAIO.R3.SourceGenerators
The package is a DevelopmentDependency analyzer. Add using R3.SourceGenerators; for extension methods. Generated interfaces and implementations are internal in that namespace.
Quick start
FromEvents / FromEventHandlers
public class Button : Control
{
public event EventHandler<RoutedEventArgs>? Click;
}
// Returns IButtonEvents (internal interface).
var clicks = button.FromEvents().Click;
Hierarchy — one entry point, events from bases and interfaces:
public class BaseSource { public event Action? BaseChanged; }
public interface INotify { event EventHandler? Notified; }
public class DerivedSource : BaseSource, INotify
{
public event Action<int>? DerivedChanged;
public event EventHandler? Notified { add; remove; }
}
DerivedSource d = new();
_ = d.FromEvents().BaseChanged;
_ = d.FromEvents().Notified;
_ = d.FromEvents().DerivedChanged;
Generic constraints:
static void Run<T>(T source) where T : BaseSource, IFirst, ISecond
{
_ = source.FromEvents().BaseChanged;
_ = source.FromEvents().FirstChanged;
_ = source.FromEvents().SecondChanged;
}
Routed events (WPF / Avalonia)
Same interface + property model as FromEvents (e.g. IButtonRoutedEvents). Parameterless calls use default Avalonia routes (Direct | Bubble, handledEventsToo: false).
var clicks = button.FromRoutedEvents().Click;
var clickHandlers = button.FromRoutedEventHandlers().Click;
Explicit routing (Avalonia):
var pointerPressed = control
.FromRoutedEvents(
Avalonia.Interactivity.RoutingStrategies.Tunnel | Avalonia.Interactivity.RoutingStrategies.Bubble,
handledEventsToo: true)
.PointerPressed;
Attached routed events (still Observable<T> extensions, not the interface model):
var childClicks = panel.FromAttachedRoutedEvent(
Avalonia.Controls.Button.ClickEvent,
Avalonia.Interactivity.RoutingStrategies.Bubble,
handledEventsToo: true);
Interface-only event sources
public interface INotifyMore : INotifySomething
{
event Action? MoreChanged;
}
static void Run(INotifyMore s)
{
_ = s.FromEvents().SomethingChanged;
_ = s.FromEvents().MoreChanged;
}
[R3Command]
Apply to instance methods on a partial class or struct. The generator adds a public {Name}Command property (or CommandName) backed by ReactiveCommand.
Minimal example:
public partial class ShellViewModel
{
private readonly Observable<bool> _canSave = new(true);
[R3Command(CanExecute = nameof(_canSave))]
private async Task Save() { /* ... */ }
}
Method signature matrix
| Parameters | Return type | Generated property type | Notes |
|---|---|---|---|
| none | void |
ReactiveCommand |
Sync handler |
one (T) |
void |
ReactiveCommand<T> |
Sync with argument |
| none | Task |
ReactiveCommand |
Async; wrapped as ValueTask in handler |
one (T) |
Task |
ReactiveCommand<T> |
Async with argument |
| none | ValueTask |
ReactiveCommand |
Same as Task without result |
one (T) |
ValueTask |
ReactiveCommand<T> |
|
one (T) |
Task<TResult> |
ReactiveCommand<T, TResult> |
Result type from TResult |
one (T) |
ValueTask<TResult> |
ReactiveCommand<T, TResult> |
|
| none | Task<TResult> / ValueTask<TResult> |
— | Not supported (R3SG1001) |
| two or more parameters | any | — | Not supported (R3SG1001) |
static method |
any | — | Not supported (R3SG1001) |
Attribute members
| Attribute property | Effect |
|---|---|
| (none) | Property name {MethodName}Command |
CommandName = "Submit" |
Property name Submit |
CanExecute = nameof(_canSave) |
Passes _canSave into ReactiveCommand ctor; must exist on the same partial type and be Observable<bool> or IObservable<bool> |
Diagnostics
| Id | When |
|---|---|
R3SG0001 |
Declaring type is not partial |
R3SG1001 |
Method signature not in the matrix above |
R3SG1002 |
CanExecute member name not found |
R3SG1003 |
CanExecute type is not Observable<bool> / IObservable<bool> |
R3SG1004 |
Two methods would generate the same command property name |
Event-related warnings (R3SG2001, R3SG2002) apply to unsupported event delegate shapes for FromEvents / FromEventHandlers.
Design documentation
- Interface-based event generation — naming, hierarchy, routed events, file layout.
- CHANGELOG.md — release notes and upgrade compatibility (including SyntaxFactory internal migration).
Samples
Runnable demos: MvvmAIO.R3.SourceGenerators.Samples (WPF + Avalonia).
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.