RxBlazorV2 1.0.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package RxBlazorV2 --version 1.0.3
                    
NuGet\Install-Package RxBlazorV2 -Version 1.0.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="RxBlazorV2" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RxBlazorV2" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="RxBlazorV2" />
                    
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 RxBlazorV2 --version 1.0.3
                    
#r "nuget: RxBlazorV2, 1.0.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 RxBlazorV2@1.0.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=RxBlazorV2&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=RxBlazorV2&version=1.0.3
                    
Install as a Cake Tool

RxBlazorV2

License: MIT .NET NuGet Build and Test GitHub Repo stars

A reactive programming framework for Blazor applications built on top of R3 (Reactive Extensions). RxBlazorV2 uses Roslyn source generators to automatically create observable models with reactive property bindings, command patterns, and dependency injection support.

Live Demo

Features

  • Reactive State Management: Automatic change notifications using R3 observables
  • Source Generation: Zero runtime reflection - all code generated at compile time
  • Command Pattern: Declarative observable commands with automatic CanExecute support
  • Return Commands: Commands that return values (sync and async)
  • Model References: Automatic cross-model reactive subscriptions via partial constructors
  • DI Integration: Automatic service registration with configurable lifetimes
  • Observable Collections: Built-in support for reactive collections with batch updates
  • Generic Models: Full support for generic observable models with type constraints
  • Component Generation: Automatic Blazor component generation with [ObservableComponent]
  • Trigger System: Multiple trigger types for different reactive scenarios
  • Notification Batching: Suspend/resume change notifications for bulk updates

Installation

dotnet add package RxBlazorV2

The package includes the source generator and code fixes automatically.

Companion Packages

Package Description
RxBlazorV2.MudBlazor Reactive MudBlazor button components with progress indicators, cancellation, and confirmation dialogs

Quick Start

[ObservableModelScope(ModelScope.Scoped)]
[ObservableComponent]
public partial class CounterModel : ObservableModel
{
    public partial int Count { get; set; }

    [ObservableCommand(nameof(Increment))]
    public partial IObservableCommand IncrementCommand { get; }

    private void Increment() => Count++;
}
@page "/counter"
@inherits CounterModelComponent

<p>Count: @Model.Count</p>
<button @onclick="() => Model.IncrementCommand.Execute()">Increment</button>

Core Concepts

Observable Properties

Properties marked as partial with both getter and setter are automatically enhanced with change notifications, value equality checks, and integration with the reactive observable stream.

public partial class MyModel : ObservableModel
{
    public partial string Name { get; set; } = "Default";
    public partial int Count { get; set; }
}

Observable Commands

Commands link UI actions to model methods with automatic CanExecute tracking.

Interface Description
IObservableCommand Sync, no parameters
IObservableCommand<T> Sync with parameter
IObservableCommandAsync Async, no parameters
IObservableCommandAsync<T> Async with parameter and cancellation
IObservableCommandR<T> Sync with return value
IObservableCommandR<T1, T2> Sync with parameter and return value
IObservableCommandRAsync<T> Async with return value
IObservableCommandRAsync<T1, T2> Async with parameter and return value
[ObservableCommand(nameof(Save), nameof(CanSave))]
public partial IObservableCommandAsync SaveCommand { get; }

[ObservableCommand(nameof(Calculate))]
public partial IObservableCommandR<int> CalculateCommand { get; }

private async Task Save() { /* ... */ }
private bool CanSave() => !string.IsNullOrEmpty(Name);
private int Calculate() => Count * 2;

Model References (Partial Constructor Pattern)

Models can reference and react to changes in other models through the partial constructor pattern:

[ObservableModelScope(ModelScope.Scoped)]
public partial class ShoppingCartModel : ObservableModel
{
    // Declare dependencies via partial constructor
    public partial ShoppingCartModel(ProductCatalogModel catalog, ILogger logger);

    // Generator creates:
    // - protected ProductCatalogModel Catalog { get; } with auto-subscription
    // - private readonly ILogger _logger field

    public partial decimal Total { get; set; }

    private void RecalculateTotal()
    {
        Total = Quantity * Catalog.Price; // Access referenced model
    }
}

Key Points:

  • ObservableModel parameters become protected properties with auto-subscription
  • Other service parameters become private readonly fields with underscore prefix
  • Observable streams are automatically merged from referenced models

Component Generation

Use [ObservableComponent] to generate a Blazor component base class:

[ObservableModelScope(ModelScope.Scoped)]
[ObservableComponent] // Generates MyModelComponent
public partial class MyModel : ObservableModel
{
    public partial string Title { get; set; }
}
@page "/mypage"
@inherits MyModelComponent

<h1>@Model.Title</h1>

Options:

  • componentName: Custom component class name (default: {ModelName}Component)
  • includeReferencedTriggers: Include triggers from referenced models (default: true)

Trigger System

RxBlazorV2 provides multiple trigger types for different reactive scenarios:

Component Triggers

Generate hook methods in components for property changes:

[ObservableComponent]
public partial class SettingsModel : ObservableModel
{
    // Generates OnThemeChanged() hook in component
    [ObservableComponentTrigger]
    public partial string Theme { get; set; }

    // Async hook with custom name
    [ObservableComponentTriggerAsync(hookMethodName: "HandleDarkModeToggle")]
    public partial bool IsDarkMode { get; set; }

    // Render only - no hook generated
    [ObservableComponentTrigger(ComponentTriggerType.RenderOnly)]
    public partial int Counter { get; set; }

    // Hook only - no re-render
    [ObservableComponentTrigger(ComponentTriggerType.HookOnly)]
    public partial string BackgroundTask { get; set; }
}

ComponentTriggerType Options:

  • RenderAndHook (default): Calls hook AND re-renders component
  • RenderOnly: Re-renders but no hook method
  • HookOnly: Calls hook but no automatic re-render

Property Triggers

Execute internal methods automatically when properties change:

public partial class ValidationModel : ObservableModel
{
    [ObservableTrigger(nameof(ValidateEmail))]
    public partial string Email { get; set; }

    [ObservableTriggerAsync(nameof(SaveAsync), nameof(CanSave))]
    public partial string Data { get; set; }

    private void ValidateEmail() { /* validation */ }
    private async Task SaveAsync() { /* save */ }
    private bool CanSave() => !string.IsNullOrEmpty(Data);
}

Callback Triggers

Allow external services to subscribe to property changes:

public partial class AuthModel : ObservableModel
{
    [ObservableCallbackTrigger]
    public partial ClaimsPrincipal? CurrentUser { get; set; }
}

// In external service:
public class AuthService
{
    public AuthService(AuthModel authModel)
    {
        authModel.OnCurrentUserChanged(() =>
        {
            // React to user changes
        });
    }
}

Command Triggers

Auto-execute commands when properties change:

public partial class SearchModel : ObservableModel
{
    public partial string Query { get; set; }

    [ObservableCommand(nameof(Search))]
    [ObservableCommandTrigger(nameof(Query))]
    public partial IObservableCommandAsync SearchCommand { get; }

    private async Task Search() { /* search logic */ }
}

Notification Batching

Group property changes for single notifications:

public partial class FormModel : ObservableModel
{
    [ObservableBatch("userInfo")]
    public partial string FirstName { get; set; }

    [ObservableBatch("userInfo")]
    public partial string LastName { get; set; }

    public void UpdateUser(string first, string last)
    {
        using (SuspendNotifications("userInfo"))
        {
            FirstName = first;
            LastName = last;
        } // Single notification fired here
    }
}

Key Attributes

Attribute Target Description
[ObservableModelScope] Class DI lifetime (Singleton, Scoped, Transient)
[ObservableComponent] Class Generate component base class
[ObservableCommand] Property Link command to implementation method
[ObservableComponentTrigger] Property Generate component hook (sync)
[ObservableComponentTriggerAsync] Property Generate component hook (async)
[ObservableTrigger] Property Execute method on change (sync)
[ObservableTriggerAsync] Property Execute method on change (async)
[ObservableCallbackTrigger] Property Generate callback registration (sync)
[ObservableCallbackTriggerAsync] Property Generate callback registration (async)
[ObservableCommandTrigger] Property Auto-execute command on property change
[ObservableBatch] Property Group for batched notifications

Architecture

Key Design Principles:

  • Model Level: Immediate, synchronous notifications for data integrity
  • Consumer Level: Batched, chunked updates for UI performance
  • No Runtime Reflection: All code generated at compile time
  • Type Safety: Full IntelliSense and compile-time checking

Requirements

  • .NET 10.0 or later
  • C# 14 (for partial constructors and field keyword)
  • R3 v1.3.0 or later

Sample Application

See the RxBlazorV2Sample project for comprehensive, interactive examples:

Sample Description
BasicCommands Sync/async commands and observable properties
BasicCommandWithReturn Commands that return values
ParameterizedCommands Commands with type-safe parameters
CommandsWithCanExecute Conditional command execution
CommandsWithCancellation Long-running async with cancellation
CommandTriggers Auto-execute commands on property changes
ComponentTriggers Component hooks for property changes
PropertyTriggers Internal method execution on changes
CallbackTriggers External service subscriptions
ModelReferences Cross-model reactive subscriptions
ModelPatterns Partial constructor pattern examples
GenericModels Generic observable models with DI
ObservableBatches Batched property notifications
ValueEquality Automatic value equality
CrossComponentCommunication Share models across components

Run the sample application:

dotnet run --project RxBlazorV2Sample

Project Structure

  • RxBlazorV2 - Core runtime library with base classes and interfaces
  • RxBlazorV2Generator - Roslyn source generator for code generation
  • RxBlazorV2CodeFix - Code analyzers and fixes for common issues
  • RxBlazorV2.MudBlazor - MudBlazor button components with command binding
  • RxBlazorV2Sample - Sample Blazor WebAssembly application

Diagnostics

The generator provides comprehensive diagnostics (RXBG001-RXBG072) with code fixes. See the Diagnostics Help folder for detailed documentation.

Contributing

Contributions are welcome! Please ensure:

  • All tests pass
  • Code follows existing patterns
  • Source generator changes include corresponding tests

License

This project is licensed under the MIT License - see the LICENSE file for details.

Credits

Built with:

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on RxBlazorV2:

Package Downloads
RxBlazorV2.MudBlazor

Reactive MudBlazor button components for RxBlazorV2. Provides automatic progress indicators, cancellation support, and confirmation dialogs for command bindings.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.2 43 4/27/2026
1.2.1 96 4/16/2026
1.2.0 106 4/15/2026 1.2.0 is deprecated because it has critical bugs.
1.1.5 122 4/3/2026
1.1.4 98 4/2/2026
1.1.3 112 4/1/2026
1.1.2 164 12/20/2025
1.1.1 196 12/20/2025 1.1.1 is deprecated because it has critical bugs.
1.1.0 197 12/20/2025 1.1.0 is deprecated because it has critical bugs.
1.0.9 201 12/20/2025 1.0.9 is deprecated because it has critical bugs.
1.0.8 290 12/18/2025
1.0.7 289 12/18/2025
1.0.6 368 12/17/2025
1.0.5 308 12/15/2025
1.0.4 156 12/11/2025
1.0.3 234 12/4/2025
1.0.1 335 12/3/2025 1.0.1 is deprecated because it has critical bugs.
1.0.0 156 11/29/2025

v1.0.0 - Initial Release
     - ObservableModel base class with R3 reactive state management
     - Roslyn incremental source generator for partial properties and commands
     - Automatic DI registration with AddObservableModels()
     - Component triggers for reactive UI updates
     - Property triggers for internal model methods
     - Callback triggers for external service subscriptions
     - Code fixes for common patterns