DionTools.EventAsR3ObservableSourceGenerator 0.0.3-alpha.3

This is a prerelease version of DionTools.EventAsR3ObservableSourceGenerator.
dotnet add package DionTools.EventAsR3ObservableSourceGenerator --version 0.0.3-alpha.3
                    
NuGet\Install-Package DionTools.EventAsR3ObservableSourceGenerator -Version 0.0.3-alpha.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DionTools.EventAsR3ObservableSourceGenerator" Version="0.0.3-alpha.3">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DionTools.EventAsR3ObservableSourceGenerator" Version="0.0.3-alpha.3" />
                    
Directory.Packages.props
<PackageReference Include="DionTools.EventAsR3ObservableSourceGenerator">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DionTools.EventAsR3ObservableSourceGenerator --version 0.0.3-alpha.3
                    
#r "nuget: DionTools.EventAsR3ObservableSourceGenerator, 0.0.3-alpha.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DionTools.EventAsR3ObservableSourceGenerator@0.0.3-alpha.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DionTools.EventAsR3ObservableSourceGenerator&version=0.0.3-alpha.3&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=DionTools.EventAsR3ObservableSourceGenerator&version=0.0.3-alpha.3&prerelease
                    
Install as a Cake Tool

EventAsR3ObservableSourceGenerator

NuGet License: MIT

日本語版はこちら

A C# source generator that automatically creates extension methods to convert .NET events into R3.Observable.

Overview

Working with .NET events in a reactive programming style typically requires manual boilerplate code to convert events to observables. This source generator automates that process by analyzing your classes at compile time and generating the necessary extension methods.

Benefits:

  • ✅ Type-safe observable for your events
  • ✅ Supports instance events, static events, and generic types
  • ✅ Configurable method naming

Features

  • Instance Events: Generate observable extensions for instance-level events
  • Static Events: Generate observable extensions for static events
  • Generic Type Support: Full support for generic classes with type constraints
  • Inherited Events: Handle events in derived classes
  • Customizable Naming: Configure method name prefixes and suffixes
  • Event Handler Modes: Choose between EventArgs-only or (sender, EventArgs) tuple emissions

Prerequisites

  • Visual Studio 2022 Version 17.3 (Incremental Source Generator, Roslyn 4.3.0) or later
  • C# 9 or later
  • R3

Installation

Install via NuGet Package Manager:

dotnet add package DionTools.EventAsR3ObservableSourceGenerator

Quick Start

// 1. Define a class with events
class MyButton
{
    public event EventHandler? Clicked;
}

// 2. Mark a partial class with the generation attribute
[EventAsR3ObservableSourceGenerator.EventAsObservablesGeneration(typeof(MyButton))]
static partial class Extensions;

// 3. Use the generated extension method
var button = new MyButton();
R3.Observable<EventArgs> clicks = button.ClickedAsObservable();

Usage

Basic Instance Events

class NormalClass
{
    public event EventHandler? NormalEvent;
}

// Generate extension methods for NormalClass
[EventAsR3ObservableSourceGenerator.EventAsObservablesGeneration(typeof(NormalClass))]
static partial class Extensions;

// Usage
R3.Observable<EventArgs> obs = new NormalClass().NormalEventAsObservable();

Static Events

static class StaticEvents
{
    public static event EventHandler? StaticEvent;
    public static event ConsoleCancelEventHandler? CancelKeyPress;
}

// Generate extension methods for static events
[EventAsR3ObservableSourceGenerator.StaticEventAsObservablesGeneration(typeof(StaticEvents))]
static partial class StaticEventsExtensions;

// Usage
R3.Observable<EventArgs> obs1 = StaticEventsExtensions.StaticEventAsObservable();
R3.Observable<ConsoleCancelEventArgs> obs2 = StaticEventsExtensions.CancelKeyPressAsObservable();

Generic Classes

class GenericClass<T>
{
    public event EventHandler<T>? GenericEvent;
}

class GenericClassWithConstraints<T> where T : NormalClass
{
    public event EventHandler<T>? GenericEvent;
}

// Generate extension methods for generic types
[EventAsR3ObservableSourceGenerator.EventAsObservablesGeneration(typeof(GenericClass<>))]
[EventAsR3ObservableSourceGenerator.EventAsObservablesGeneration(typeof(GenericClassWithConstraints<>))]
static partial class GenericExtensions;

// Usage
R3.Observable<int> obs1 = new GenericClass<int>().GenericEventAsObservable();
R3.Observable<MyClass> obs2 = new GenericClassWithConstraints<MyClass>().GenericEventAsObservable();

Inherited Classes

class BaseClass
{
    public event EventHandler? BaseEvent;
}

class DerivedClass : BaseClass
{
    public new event EventHandler<string>? BaseEvent;
}

[EventAsR3ObservableSourceGenerator.EventAsObservablesGeneration(typeof(BaseClass))]
[EventAsR3ObservableSourceGenerator.EventAsObservablesGeneration(typeof(DerivedClass))]
static partial class InheritanceExtensions;

// Each class gets its own observable with the correct type
R3.Observable<EventArgs> baseObs = new BaseClass().BaseEventAsObservable();
R3.Observable<string> derivedObs = new DerivedClass().BaseEventAsObservable();

Generated Code

For a class with an event:

// Your code
class MyClass
{
    public event EventHandler<int>? ValueChanged;
}

[EventAsR3ObservableSourceGenerator.EventAsObservablesGeneration(typeof(MyClass))]
static partial class Extensions;

The generator creates an extension method like this:

// Generated code (simplified)
static partial class Extensions
{
    public static R3.Observable<int> ValueChangedAsObservable(this MyClass self, CancellationToken cancellationToken = default)
    {
        return EventAsR3ObservableSourceGenerator.Internals.EventObservable<MyClass, EventHandler<int>, int>(
            self,
            static h => (s, e) => h(e),
            static (self, h) => self.ValueChanged += h,
            static (self, h) => self.ValueChanged -= h,
            cancellationToken
        );
    }
}

Configuration

EventAsObservablesGenerationOptions

You can customize the generated methods using the EventAsObservablesGenerationOptions attribute:

[EventAsR3ObservableSourceGenerator.EventAsObservablesGenerationOptions(
    UseEventHandler = true,
    MethodNamePrefix = "Observe",
    MethodNameSuffix = ""
)]
[EventAsR3ObservableSourceGenerator.EventAsObservablesGeneration(typeof(MyClass))]
static partial class Extensions;
Property Description Default
UseEventHandler When true, emits (object? sender, TEventArgs args) tuples. When false, emits only TEventArgs. false
MethodNamePrefix Prefix for generated method names "" (empty)
MethodNameSuffix Suffix for generated method names "AsObservable"

Example with options:

// With UseEventHandler = true
Observable<(object? sender, int args)> obs = myObject.ObserveClick();

// With UseEventHandler = false (default)
Observable<int> obs = myObject.ObserveClick();
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .NETStandard 2.0

    • 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.

Version Downloads Last Updated
0.0.3-alpha.3 202 11/2/2025
0.0.3-alpha.2 189 11/2/2025
0.0.3-alpha.1 190 11/2/2025
0.0.2-alpha.3 188 11/2/2025
0.0.2-alpha.2 205 11/2/2025
0.0.2-alpha.1 198 11/2/2025