redb.Route
2.0.2
Prefix Reserved
dotnet add package redb.Route --version 2.0.2
NuGet\Install-Package redb.Route -Version 2.0.2
<PackageReference Include="redb.Route" Version="2.0.2" />
<PackageVersion Include="redb.Route" Version="2.0.2" />
<PackageReference Include="redb.Route" />
paket add redb.Route --version 2.0.2
#r "nuget: redb.Route, 2.0.2"
#:package redb.Route@2.0.2
#addin nuget:?package=redb.Route&version=2.0.2
#tool nuget:?package=redb.Route&version=2.0.2
redb.Route
Core ESB engine — async-first message routing with fluent C# DSL, 24 EIP processors, unified expression engine with 17 predicates, OpenTelemetry telemetry, and built-in components (Direct, SEDA, Timer, Mock, Log).
Installation
dotnet add package redb.Route
Quick Start
using redb.Route.Extensions;
builder.Services.AddRedbRoute(route =>
{
// Inline routes
route.AddRoutes(r =>
{
r.From("timer://heartbeat?period=5000")
.SetBody("ping")
.Log("Heartbeat: ${body}")
.To("direct://monitor");
});
// Or RouteBuilder classes
route.AddRouteBuilder<MyRoutes>();
});
RouteBuilder — Full DSL
public class OrderRoutes : RouteBuilder
{
protected override void Configure()
{
From("direct://orders")
.RouteId("order-pipeline")
// Expression predicates — typed, composable
.Filter(Header("status").isEqualTo("new"))
// JsonPath extraction
.SetBody(JPath("$.order"))
.SetHeader("total", JPath<decimal>("$.order.total"))
// Content-Based Router — chain style
.Choice()
.When(Header("total").isGreaterThan(10000))
.To("direct://large-orders")
.When(Header("total").isBetween(1000, 10000))
.To("direct://medium-orders")
.Otherwise()
.To("direct://small-orders")
.EndChoice()
.Log("Order routed: ${header.orderId}");
// Exception handling with redelivery
OnException<HttpRequestException>()
.MaximumRedeliveries(3)
.RedeliveryDelay(TimeSpan.FromSeconds(2))
.UseExponentialBackOff()
.BackOffMultiplier(2.0)
.Handled()
.Log("HTTP error: ${exception.message}")
.To("seda://dead-letter")
.EndOnException();
}
}
Built-in Components
| Component | Scheme | Direction | Description |
|---|---|---|---|
| Direct | direct:name |
In-process | Synchronous in-process messaging |
| SEDA | seda:name |
In-process | Async queue with configurable concurrency |
| Timer | timer:name |
Consumer | Periodic message generation |
| Mock | mock:name |
Producer | Testing endpoint with expectations |
| Log | log:name |
Producer | Logging sink at configurable levels |
Fluent Builders
using redb.Route.Fluent;
// Direct — sync in-process
From(Direct.Endpoint("orders"))
.To(Direct.Endpoint("processor"));
// SEDA — async queue
From(Seda.Consume("incoming").ConcurrentConsumers(4).Size(1000))
.To(Seda.Send("outgoing"));
// Timer — periodic
From(TimerDsl.Every("poll").Period(5000).Delay(1000))
.To("direct://check");
// Mock — testing
From("direct://test")
.To(MockDsl.Endpoint("result").ExpectedMessageCount(3));
// Log — sink
From("direct://data")
.To(LogDsl.Info("audit").ShowHeaders().ShowBody());
Expression Engine
Two expression systems — unified through IExpression interface:
Typed Expressions (RouteBuilder helpers)
protected static helpers in RouteBuilder — use directly in Configure():
// Message accessors
Body() // message body
Header("name") // header value
Property("key") // exchange property
Constant(42) // constant value
Exchange(e => e.RouteId) // delegate over IExchange
// Structured data extraction
JPath("$.order.total") // JsonPath
JPath<decimal>("$.order.total") // typed JsonPath
XPath("/order/status/text()") // XPath 1.0
XPath<int>("count(//item)") // typed XPath
// String template bridge — wraps ${...} as IExpression
Expr("${header.orderId}") // single value
Expr("${header.prefix}-${body}") // template interpolation
17 Predicate Methods
Every expression supports predicate chaining — for Filter(), When(), Validate():
Header("status").isEqualTo("active") // equality
Header("status").isNotEqualTo("cancelled") // inequality
Header("amount").isGreaterThan(1000) // comparison
Header("amount").isLessThan(500)
Header("amount").isGreaterThanOrEqualTo(100)
Header("amount").isLessThanOrEqualTo(9999)
Header("amount").isBetween(100, 5000) // range (inclusive)
Header("name").contains("Corp") // substring / collection
Header("name").startsWith("Order-")
Header("name").endsWith(".pdf")
Header("email").regex(@"^[\w.]+@[\w.]+$") // regex match
Header("type").In("order", "payment") // set membership
Header("optional").isNull()
Header("required").isNotNull()
// Also works with Expr — string expression + predicates:
Expr("${header.amount}").isGreaterThan(1000)
String Expression Resolver
AST-based compiled expression language with caching (used in Log, Filter(string), When(string), Expr()):
// Templates — ${...} placeholder interpolation
.Log("Processing: ${header.orderId}")
.SetBody(Expr("${header.prefix}-${body}"))
// Boolean expressions — in Filter/When
.Filter("header.amount > 1000")
.Filter("header.status == 'active' AND header.amount > 0")
// Supports: header.*, body.*, property.*, exception.*
// Operators: ==, !=, >, <, >=, <=, AND, OR, XOR, !
// Functions: contains(), startsWith(), endsWith(), jpath(), xpath()
// Arithmetic: +, -, *, /
Every DSL Method — Multiple Input Styles
| Method | Static | Lambda | IExpression | String ${...} |
|---|---|---|---|---|
SetBody |
SetBody("hi") |
SetBody(e => ...) |
SetBody(Header("x")) |
SetBody(Expr("${header.x}")) |
SetHeader |
SetHeader("k","v") |
SetHeader("k", e => ...) |
SetHeader("k", JPath("$.x")) |
SetHeader("k", Expr("${body}")) |
SetProperty |
SetProperty("k",1) |
SetProperty("k", e => ...) |
SetProperty("k", Body()) |
SetProperty("k", Expr("${header.x}")) |
Filter |
— | Filter(e => ...) |
Filter(Header("x").isEqualTo("y")) |
Filter("header.x == 'y'") |
Transform |
— | Transform(e => ...) |
Transform(JPath("$.data")) |
— |
Process |
— | Process(e => ...) |
Process(myProcessor) |
— |
Processors (24 EIP Patterns)
| Processor | DSL | Pattern |
|---|---|---|
PipelineProcessor |
(implicit) | Pipeline |
FilterProcessor |
.Filter(...) |
Message Filter |
ChoiceProcessor |
.Choice() |
Content-Based Router |
MulticastProcessor |
.Multicast(...) |
Multicast |
RecipientListProcessor |
.RecipientList(...) |
Recipient List |
SplitterProcessor |
.Split(...) |
Splitter |
AggregatorProcessor |
.Aggregate(...) |
Aggregator |
ResequencerProcessor |
.Resequence(...) |
Resequencer |
DynamicRouterProcessor |
.DynamicRouter(...) |
Dynamic Router |
WireTapProcessor |
.WireTap(...) |
Wire Tap |
EnrichProcessor |
.Enrich(...) |
Content Enricher |
ToProcessor |
.To(...) |
Message Endpoint |
DelegateProcessor |
.Process(...) |
Custom Processor |
LogProcessor |
.Log(...) |
Logging |
RichLogProcessor |
.Log().Message(...) |
Structured Logging |
DelayProcessor |
.Delay(...) |
Delayer |
LoopProcessor |
.Loop(...) |
Loop |
ThrottleProcessor |
.Throttle(...) |
Throttler |
CircuitBreakerProcessor |
.CircuitBreaker(...) |
Circuit Breaker |
RetryProcessor |
.Retry(...) |
Retry |
DeadLetterProcessor |
.DeadLetterChannel(...) |
Dead Letter Channel |
OnExceptionProcessor |
.OnException<T>() |
Exception Handler |
TryCatchProcessor |
.DoTry() |
Try-Catch |
IdempotentConsumerProcessor |
.IdempotentConsumer(...) |
Idempotent Consumer |
Error Handling
// Retry with delay
.Retry(maxRetries: 3, initialDelay: TimeSpan.FromSeconds(1))
// Dead Letter Channel
.DeadLetterChannel("seda://failed")
// Try-Catch-Finally scope
.DoTry()
.To("http://api/submit")
.DoCatch<HttpRequestException>()
.Log("API failed: ${exception.message}")
.To("seda://retry")
.DoFinally()
.Log("Attempt done")
.End()
Content-Based Routing
// Chain style — Camel-like
.Choice()
.When(Header("type").isEqualTo("order"))
.To("direct://orders")
.When(Header("type").isEqualTo("payment"))
.To("direct://payments")
.Otherwise()
.To("seda://unknown")
.EndChoice()
// Lambda style — callback sub-routes
.Choice(c => c
.When(Header("type").isEqualTo("order"), r => r.To("direct://orders"))
.When(Header("type").isEqualTo("payment"), r => r.To("direct://payments"))
.Otherwise(r => r.To("seda://unknown")))
// String expression style
.Choice()
.When("header.type == 'order'")
.To("direct://orders")
.Otherwise()
.To("seda://unknown")
.EndChoice()
Processing
// Async delegate with CancellationToken
.Process(async (exchange, ct) =>
{
var order = exchange.In.Body as Order;
exchange.In.Body = await EnrichOrder(order, ct);
})
// Sync delegate
.Process(exchange =>
{
exchange.In.Headers["processed"] = true;
})
// Custom IProcessor class
.Process(new OrderValidationProcessor())
Configuration
builder.Services.Configure<RouteEngineOptions>(o =>
{
o.EnableTelemetry = true; // OpenTelemetry Activities
o.EnableMetrics = true; // Meters & Counters
o.ShutdownTimeout = TimeSpan.FromSeconds(30);
o.ThrowOnCompilationError = true; // Fail-fast on invalid routes
});
Telemetry
Built-in OpenTelemetry — distributed tracing + metrics per route and step:
// Scope style — wrap block of steps
.Traced("order-processing")
.SetBody(JPath("$.order"))
.Process(async (e, ct) => await Enrich(e, ct))
.EndTraced()
// Inline style — wrap single step
.Traced("validate", async (e, ct) => await Validate(e, ct))
.Metered("throughput", e => { e.In.Body = Transform(e); })
Validation
// JSON Schema
.ValidateJsonSchema("""{"type":"object","required":["orderId"]}""")
// XSD
.ValidateXsd(xsdContent)
// Predicate
.Validate(e => e.In.Body is Order { Amount: > 0 }, "Amount must be positive")
Part of
redb.Route — ESB & EIP Framework for .NET
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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 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. |
-
net10.0
- JsonPath.Net (>= 2.0.0)
- JsonSchema.Net (>= 7.3.4)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.3)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Options (>= 10.0.3)
- Newtonsoft.Json (>= 13.0.3)
-
net8.0
- JsonPath.Net (>= 2.0.0)
- JsonSchema.Net (>= 7.3.4)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 8.0.8)
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options (>= 8.0.2)
- Newtonsoft.Json (>= 13.0.3)
-
net9.0
- JsonPath.Net (>= 2.0.0)
- JsonSchema.Net (>= 7.3.4)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.3)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 9.0.3)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.3)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.3)
- Microsoft.Extensions.Options (>= 9.0.3)
- Newtonsoft.Json (>= 13.0.3)
NuGet packages (26)
Showing the top 5 NuGet packages that depend on redb.Route:
| Package | Downloads |
|---|---|
|
redb.Route.Ldap
LDAP/Active Directory transport for redb.Route ESB framework. Provides Search, Add, Modify, Delete, Compare, Bind operations and directory change polling consumer. |
|
|
redb.Route.Http
HTTP transport for redb.Route ESB framework. Provides HttpClient producer and Kestrel-based consumer (webhook receiver) with CORS, auth, and streaming support. |
|
|
redb.Route.Controllers
Transport-agnostic controller dispatch for redb.Route ESB framework. Provides RedbController base class, attribute-based routing, parameter binding, and ControllerDispatcherProcessor. |
|
|
redb.Route.Quartz
Quartz.NET scheduling transport for redb.Route ESB framework. Provides Cron and QuartzTimer components. |
|
|
redb.Route.Core
Bridge package connecting redb.Route ESB framework with redb.Core EAV storage. Provides RedbIdempotentRepository, typed access to IRedbService from route pipelines, and extension methods for redb.Core integration. |
GitHub repositories
This package is not used by any popular GitHub repositories.