Routya.Core
1.0.0-alpha.4
See the version list below for details.
dotnet add package Routya.Core --version 1.0.0-alpha.4
NuGet\Install-Package Routya.Core -Version 1.0.0-alpha.4
<PackageReference Include="Routya.Core" Version="1.0.0-alpha.4" />
<PackageVersion Include="Routya.Core" Version="1.0.0-alpha.4" />
<PackageReference Include="Routya.Core" />
paket add Routya.Core --version 1.0.0-alpha.4
#r "nuget: Routya.Core, 1.0.0-alpha.4"
#:package Routya.Core@1.0.0-alpha.4
#addin nuget:?package=Routya.Core&version=1.0.0-alpha.4&prerelease
#tool nuget:?package=Routya.Core&version=1.0.0-alpha.4&prerelease
Routya
Routya is a fast, lightweight message dispatching library built for .NET applications that use the CQRS pattern.
It provides a flexible way to route requests/responses and notifications to their respective handlers with minimal overhead and high performance.
๐ง Routya is currently in alpha โ APIs may change as we refine the design and gather feedback.
โจ Features
- โ Clean interface-based abstraction for Requests/Responses and Notifications
- ๐ High-performance dispatching via compiled delegates (no reflection or dynamic resolution)
- ๐งฉ Optional pipeline behavior support for cross-cutting concerns
- ๐ Supports both sequential and parallel notification dispatching
- โป๏ธ Simple to extend and integrate with your existing architecture
- ๐งช Built with performance and clarity in mind
๐ฆ NuGet Package
Latest prerelease version:
dotnet add package Routya.Core --version 1.0.0-alpha.4
๐ Quick Start
Dependency injection
On startup you can define if Routya should create a new instance of the service provider each time it is called or work on the root service provider.
Note!!! By default scope is enabled
Scoped
builder.Services.AddRoutya(cfg => cfg.Scope = RoutyaDispatchScope.Scoped, Assembly.GetExecutingAssembly());
Root
builder.Services.AddRoutya(cfg => cfg.Scope = RoutyaDispatchScope.Root, Assembly.GetExecutingAssembly());
You can add an auto registration of IRequestHandler, IAsyncRequestHandler and INotificationHandler by adding the executing assembly
Note!!! By default you would have to manually register your Requests/Notifications and Handlers
builder.Services.AddRoutya(cfg => cfg.Scope = RoutyaDispatchScope.Scoped, Assembly.GetExecutingAssembly());
Requests
๐ Benchmark Results
Note! Benchmarks were run with handlers returning only a string using BenchmarkDotNet | Method | Mean | Error | StdDev | Code Size | Allocated | |----------------- |----------:|---------:|---------:|----------:|----------:| | Routya_Send | 76.59 us | 1.491 us | 1.831 us | 8,684 B | 6.31 KB | | Routya_SendAsync | 246.53 us | 1.848 us | 1.638 us | 8,813 B | 8.94 KB |
Define a request
public class HelloRequest(string name) : IRequest<string>
{
public string Name { get; } = name;
}
Implement the Sync handler ...
public class HelloSyncHandler : IRequestHandler<HelloRequest, string>
{
public string Handle(HelloRequest request)
{
return $"Hello, {request.Name}!";
}
}
or Implement the async handler
public class HelloAsyncHandler : IAsyncRequestHandler<HelloRequest, string>
{
public async Task<string> HandleAsync(HelloRequest request, CancellationToken cancellationToken)
{
return await Task.FromResult($"[Async] Hello, {request.Name}!");
}
}
Inject the IRoutya interface and dispatch your requests in sync...
public class Example : ControllerBase
{
private readonly IRoutya _dispatcher;
public Example(IRoutya dispatcher)
{
_dispatcher = dispatcher
}
}
_dispatcher.Send<HelloRequest, string>(new HelloRequest("Sync World"));
or async
await _dispatcher.SendAsync<HelloRequest, string>(new HelloRequest("Async World"));
Notifications
๐ Benchmark Results
Note! Benchmarks were run with handlers returning only Task.Completed using BenchmarkDotNet | Method | Mean | Error | StdDev | Code Size | Gen0 | Allocated | |-------------------------- |---------:|--------:|--------:|----------:|-------:|----------:| | RoutyaCompiled_Sequential | 315.9 ns | 2.21 ns | 1.96 ns | 368 B | 0.0019 | 528 B | | RoutyaCompiled_Parallel | 338.1 ns | 2.84 ns | 2.52 ns | 368 B | 0.0024 | 648 B |
Define your notification
public class UserRegisteredNotification(string email) : INotification
{
public string Email { get; } = email;
}
Define your handlers
public class LogAnalyticsHandler : INotificationHandler<UserRegisteredNotification>
{
public async Task Handle(UserRegisteredNotification notification, CancellationToken cancellationToken = default)
{
await Task.Delay(100, cancellationToken);
Console.WriteLine($"๐ Analytics event logged for {notification.Email}");
}
}
public class SendWelcomeEmailHandler : INotificationHandler<UserRegisteredNotification>
{
public async Task Handle(UserRegisteredNotification notification, CancellationToken cancellationToken = default)
{
await Task.Delay(200, cancellationToken);
Console.WriteLine($"๐ง Welcome email sent to {notification.Email}");
}
}
Inject the IRoutya interface and dispatch your notifications sequentially...
public class Example : ControllerBase
{
private readonly IRoutya _dispatcher;
public Example(IRoutya dispatcher)
{
_dispatcher = dispatcher
}
}
await dispatcher.PublishAsync(new UserRegisteredNotification("john.doe@example.com"));
or in parallel
await dispatcher.PublishParallelAsync(new UserRegisteredNotification("john.doe@example.com"));
Product | Versions 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 was computed. 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 was computed. 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. |
-
.NETStandard 2.1
- Microsoft.Extensions.DependencyInjection (>= 9.0.4)
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 | |
---|---|---|---|
1.0.4 | 168 | 5/6/2025 | |
1.0.3 | 295 | 4/25/2025 | |
1.0.2 | 343 | 4/24/2025 | |
1.0.1 | 351 | 4/23/2025 | |
1.0.0 | 350 | 4/22/2025 | |
1.0.0-alpha.4 | 341 | 4/16/2025 | |
1.0.0-alpha.2 | 334 | 4/15/2025 |