VitalRouter.MRuby 2.6.1

dotnet add package VitalRouter.MRuby --version 2.6.1
                    
NuGet\Install-Package VitalRouter.MRuby -Version 2.6.1
                    
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="VitalRouter.MRuby" Version="2.6.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="VitalRouter.MRuby" Version="2.6.1" />
                    
Directory.Packages.props
<PackageReference Include="VitalRouter.MRuby" />
                    
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 VitalRouter.MRuby --version 2.6.1
                    
#r "nuget: VitalRouter.MRuby, 2.6.1"
                    
#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 VitalRouter.MRuby@2.6.1
                    
#: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=VitalRouter.MRuby&version=2.6.1
                    
Install as a Cake Addin
#tool nuget:?package=VitalRouter.MRuby&version=2.6.1
                    
Install as a Cake Tool

VitalRouter

GitHub license Unity 2022.2+ .NET 6.0+

VitalRouter is a high-performance, zero-allocation in-memory messaging library for C#. It is specifically designed for environments where performance and decoupling are critical, such as Unity games or complex .NET applications.

By using simple attributes, you can implement asynchronous handlers, middleware (interceptors), and advanced sequence control. VitalRouter leverages Roslyn Source Generators to produce highly efficient code, promoting a clean, unidirectional control flow with minimal overhead.

Documentation

Visit vitalrouter.hadashikick.jp for the full documentation.

Key Features

  • Zero Allocation: Optimized for high-frequency messaging without GC pressure.
  • Thread-Safe: Designed for safe use across multiple threads.
  • Unidirectional Flow: Promotes a predictable data flow through your application.
  • Declarative Routing: Use attributes like [Routes] and [Route] to define handlers.
  • Async Interceptor Pipeline: Build sophisticated message processing chains.
  • Versatile Compatibility: Works seamlessly in both Unity and standard .NET projects.
  • DI Integration: Native support for VContainer (Unity) and Microsoft.Extensions.DependencyInjection.

Core Concepts

VitalRouter follows a simple messaging flow. A Publisher sends a Command to a Router, which then dispatches it through optional Interceptors to one or more Handlers.

---
config:
  theme: dark
---
graph LR
    Publisher[Publisher] -- PublishAsync --> Router[Router]
    subgraph Pipeline
        Router -- next --> Interceptor1[Interceptor A]
        Interceptor1 -- next --> Interceptor2[Interceptor B]
    end
    Interceptor2 -- Invoke --> Handler[Handler/Presenter]

1. Define a Command

Commands are lightweight data structures representing events or actions.

// record structs are recommended for zero-allocation messaging
public readonly record struct MoveCommand(Vector3 Destination) : ICommand;

AOT/HybridCLR Note: While record struct is valid, ensure your AOT metadata is correctly generated for iOS/AOT environments if using tools like HybridCLR.

2. Create a Handler (Presenter)

Use the [Routes] attribute on a partial class to receive commands.

[Routes]
public partial class PlayerPresenter
{
    // Use ValueTask for performance in pure .NET projects
    [Route]
    public async ValueTask On(MoveCommand cmd)
    {
        await MoveToAsync(cmd.Destination);
    }

    // Use UniTask for Unity-specific async handling
    [Route]
    public async UniTask On(SomeAsyncCommand cmd)
    {
        await DoSomethingAsync();
    }
}

3. Map and Publish

Connect your handler to a router and start sending commands.

var router = new Router();
var presenter = new PlayerPresenter();

// MapTo returns a Subscription (IDisposable)
using var subscription = presenter.MapTo(router);

// Publish a message
await router.PublishAsync(new MoveCommand(new Vector3(1, 0, 0)));

(Optional) Simple Pub/Sub

You can also subscribe with lambdas instead of using the source generator.

// Simple subscription
router.Subscribe<MoveCommand>(cmd => { /* ... */ });

// Async subscription with ordering
router.SubscribeAwait<MoveCommand>(async (cmd, ct) =>
{
    await DoSomethingAsync();
}, CommandOrdering.Sequential);

// Inline interceptors (Filters)
//
// `WithFilter(...)` returns a derived child router that owns the given filter.
// Subscribers registered on the child receive commands published on the parent
// (with the filter applied), just like an Rx `Where` chain forwards items from
// its source.
router
    .WithFilter<MoveCommand>(async (cmd, context, next) =>
    {
        Console.WriteLine("Before");
        await next(cmd, context);
        Console.WriteLine("After");
    })
    .Subscribe(cmd => { /* ... */ });

// Publishing on the parent triggers the filter for subscribers on the child:
await router.PublishAsync(new MoveCommand(...));
// → "Before" → handler → "After"

Unity Integration

VitalRouter is highly optimized for Unity, especially when combined with UniTask.

MonoBehaviour Example

When using MapTo in a MonoBehaviour, always bind the subscription to the object's lifecycle.

[Routes]
public partial class CharacterController : MonoBehaviour
{
    private void Start()
    {
        // Bind the subscription to this GameObject's lifecycle
        this.MapTo(Router.Default).AddTo(destroyCancellationToken);
    }

    [Route]
    public void On(MoveCommand cmd)
    {
        transform.position = cmd.Destination;
    }
}

Assembly Definition (.asmdef): You must reference VitalRouter in your .asmdef file for the Source Generator to process your [Routes] attributes.


UniTask Integration

UniTask is a fast async/await library for Unity. VitalRouter actively supports UniTask. Requires: UniTask >= 2.5.5

If UniTask is installed, the VITALROUTER_UNITASK_INTEGRATION flag is defined automatically, enabling optimized GC-free code paths.

Read more


Installation

Requirements

  • Unity projects: Unity 2022.2+ required for incremental source generator support.
  • Standard .NET projects: .NET 6.0+.

Packages

Package Purpose Latest version
VitalRouter Core messaging and source-generated routing NuGet
VitalRouter.Extensions.DependencyInjection DI registration for standard .NET apps NuGet
VitalRouter.R3 Bridge commands to R3 reactive streams NuGet
VitalRouter.MRuby Publish and handle commands from MRuby scripts NuGet

Unity Installation

Since version 2.0, Unity distribution has moved to NuGet.

  1. Install NuGetForUnity.
  2. Search for and install the VitalRouter packages in the NuGet window.

Optional Extensions for Unity

Install the following package to use Unity-specific features, including integration with VContainer/UniTask.

https://github.com/hadashiA/VitalRouter.git?path=/src/VitalRouter.Unity/Assets/VitalRouter#2.6.1

Advanced Features

Async Interceptor Pipeline

You can pipeline async interceptors for published messages. This is a powerful general-purpose pattern for message processing.

<img src="./website/docs/assets/diagram_interceptors.svg" alt="Interceptor Diagram" width="50%" />

Read more

R3 Integration

R3 is a next-generation Reactive Extensions implementation for C#. VitalRouter integrates with R3.

Read more

MRuby Scripting

Control command publishing via external MRuby scripts. MRuby fibers and C# async/await are fully integrated.

MRuby and C# Diagram

Read more


Appendix: Best Practices

Based on large-scale production usage (e.g., HybridFrame):

  1. Prefer record structs: For commands that are pure data, record struct provides equality comparison and zero-allocation benefits.
  2. Explicit Lifecycles: Always use .AddTo(destroyCancellationToken) or manual Dispose() to avoid memory leaks and ghost event handling.
  3. UniTask for Unity: Use UniTask or UniTaskVoid as return types in Unity handlers to leverage optimized pooling. Use ValueTask for pure .NET projects.
  4. Contextual Metadata: Use PublishContext for cross-cutting concerns (logging IDs, cancellation tokens, user permissions) instead of adding those fields to your command structs.
  5. Sequential by Default for UI: Use CommandOrdering.Sequential for UI animations or dialogue sequences to prevent race conditions.
  6. DI Integration: In Unity, VContainer (>= 1.16.6) is highly recommended for managing router lifecycles and handler registration.

License

MIT

Author

@hadashiA

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
2.6.1 80 6/3/2026
2.6.0 80 6/3/2026
2.5.0 93 5/29/2026
2.4.1 101 5/12/2026
2.4.0 98 5/11/2026
2.3.0 101 5/2/2026
2.2.0 149 2/18/2026
2.1.0 124 2/11/2026
2.0.5 133 12/31/2025
2.0.4 287 12/15/2025
2.0.3 201 11/7/2025
2.0.2 236 11/3/2025
2.0.1 220 10/31/2025
2.0.0 221 10/5/2025