redb.Route.Core
4.2.3
Prefix Reserved
dotnet add package redb.Route.Core --version 4.2.3
NuGet\Install-Package redb.Route.Core -Version 4.2.3
<PackageReference Include="redb.Route.Core" Version="4.2.3" />
<PackageVersion Include="redb.Route.Core" Version="4.2.3" />
<PackageReference Include="redb.Route.Core" />
paket add redb.Route.Core --version 4.2.3
#r "nuget: redb.Route.Core, 4.2.3"
#:package redb.Route.Core@4.2.3
#addin nuget:?package=redb.Route.Core&version=4.2.3
#tool nuget:?package=redb.Route.Core&version=4.2.3
redb.Route.Core
Bridge package connecting redb.Route ESB with redb.Core props storage. Provides persistent idempotent repository backed by redb.Core and typed access to IRedbService from route pipelines.
Installation
dotnet add package redb.Route.Core
Usage
Access IRedbService from Routes
using redb.Route.RedbCore.Extensions;
r.From("direct://save")
.ProcessWithRedb(async (redb, exchange, ct) =>
{
var order = (RedbObject<OrderProps>)exchange.In.Body!;
await redb.SaveAsync(order, ct);
});
The service is scoped to the exchange: parallel exchanges never share a connection. ProcessWithRedb("orders-db", ...)
does the same for a named database registered with context.RegisterRedbService.
Code that runs without an exchange and may run in parallel (an observer, a background job) opens a scope of its own per call:
await using var scope = context.CreateRedbScope("audit-db");
await scope.Service.SaveAsync(record, ct);
Which service you get where, hosts, transactions: docs/REDB_SERVICE_GUIDE.md.
Query storage from a route: props and base fields
RedbQuery runs a server-side query and puts the list of RedbObject<TProps> into the target. A
condition is a string in the route language: members of the stored object, compared against
values that come from the message (header.x, body, property.x, functions):
wherefilters on props, the same as redbWhere;whereRedbfilters on the base fields of the stored object, the same as redbWhereRedb:Id,ParentId,SchemeId,OwnerId,WhoChangeId,Key,Name,Note,Hash,ValueLong,ValueString,ValueGuid,ValueBool,ValueDouble,ValueNumeric,ValueDatetime,ValueUnique,DateCreate,DateModify,DateBegin,DateComplete. These are columns of the object table and usually indexed, so this is the condition that cuts the most rows before props are read.
A list of keys is one query, not a loop: member in list and member not in list become an SQL
IN in the storage, for props and base fields alike. The list is a collection the message carries
or a literal in parentheses:
whereRedb="ValueString in header.codes"
whereRedb="Id not in (7, 9)"
where="Status in ('open','held')"
Each element converts to the member's type exactly as a single compared value does, so a header of
strings works against an int field. An empty or missing list finds nothing (not in: keeps
everything); it is decided in the route and never reaches the storage as an empty IN. The member
goes on the left — a member on the right of in is refused when the route is built.
When both are written they combine with AND, because the storage cannot mix base fields and
props inside one OR. orderBy orders by a props path and orderByRedb by a base field; a
query takes one or the other. An unknown member, arithmetic over a member or an unsupported
function is refused when the route is built, never filtered in memory.
outputType picks what goes to the target:
outputType |
redb call | Target gets |
|---|---|---|
List (default) |
ToListAsync |
List<RedbObject<TProps>> |
First |
FirstOrDefaultAsync |
the first object in the query's order, or null |
Count |
CountAsync |
int |
Any |
AnyAsync |
bool |
First takes ordering and skip, not take. Count and Any answer for all the matches, so
ordering, take and skip are refused with them. Only List needs a condition or a limit: it
is the one output that loads every matching row.
r.From("direct://incident-by-key")
.RedbQuery(typeof(Incident),
whereRedb: "ValueGuid == header.correlationId",
where: "Status != 'closed'",
orderByRedb: "DateCreate", descending: true,
outputType: RedbQueryOutput.First, target: "property:incident");
The same in Route-XML:
<redbQuery type="Hub.Incident, Hub"
whereRedb="ValueGuid == header.correlationId"
where="Status != 'closed'"
orderByRedb="DateCreate" descending="true"
outputType="First" target="property:incident"/>
Persistent Idempotent Repository
Store idempotent message keys in redb.Core instead of in-memory:
using redb.Route.Core;
using redb.Route.RedbCore.Extensions;
var context = new RouteContext();
context.AddRedbIdempotentRepository("orders-inbound", ttl: TimeSpan.FromDays(7));
context.AddRoutes(r =>
{
r.From("kafka://orders?groupId=svc&brokers=localhost:9092")
.IdempotentConsumer(ex => ex.In.GetHeader<string>("messageId")!, "orders-inbound")
.To("direct://process")
.EndIdempotentConsumer();
});
The repository opens a scope of its own for every check, so it is safe under parallel consumers; inside
.Transacted() the key commits with the work.
Key Classes
| Class | Description |
|---|---|
RedbRouteExtensions |
ProcessWithRedb, SetBodyFromRedb, GetRedbService, CreateRedbScope, RegisterRedbService |
RedbIdempotentRepository |
IIdempotentRepository backed by redb.Core props storage |
RedbIdempotentOptions |
Configuration for repository scheme name and TTL |
IdempotentEntryProps |
redb.Core scheme for idempotent entries |
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
- redb.Core (>= 4.2.2)
- redb.Route (>= 4.2.3)
- redb.Route.Controllers (>= 4.2.3)
- redb.Route.Xml (>= 4.2.3)
-
net8.0
- redb.Core (>= 4.2.2)
- redb.Route (>= 4.2.3)
- redb.Route.Controllers (>= 4.2.3)
- redb.Route.Xml (>= 4.2.3)
-
net9.0
- redb.Core (>= 4.2.2)
- redb.Route (>= 4.2.3)
- redb.Route.Controllers (>= 4.2.3)
- redb.Route.Xml (>= 4.2.3)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on redb.Route.Core:
| Package | Downloads |
|---|---|
|
redb.Tsak.Core
Kernel of redb.Tsak — runtime container for redb.Route contexts. Provides hot-reload module loading, REST management API, scheduler, monitoring, security and pluggable cluster bootstrap. |
|
|
redb.Identity.Core
OAuth 2.1 / OpenID Connect engine for redb.Identity — OpenIddict pipeline on redb.Route, redb-backed stores, MFA, WebAuthn, federation, DataProtection and signing keys. |
|
|
redb.Route.Llm
Industrial LLM connector for redb.Route ESB framework. Provider-agnostic agent engine, tool-loop with governance (budget, shadow, idempotency, approval), conversation persistence via redb-engine, native EIP integration. See doc/PLAN.md. |
|
|
redb.Identity.Core.Module
redb.Tsak .tpkg host glue for redb.Identity.Core — IRouteModule entry point, configuration binding and named-redb wiring. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.2.3 | 54 | 10/8/2026 |
| 4.2.2 | 200 | 10/5/2026 |
| 4.2.0 | 199 | 9/30/2026 |
| 4.1.1 | 217 | 9/25/2026 |
| 4.1.0 | 211 | 9/21/2026 |
| 4.0.1 | 219 | 9/18/2026 |
| 4.0.0 | 233 | 9/11/2026 |
| 3.7.2 | 236 | 8/26/2026 |
| 3.7.1 | 239 | 8/26/2026 |
| 3.6.0 | 225 | 8/13/2026 |
| 3.5.1 | 210 | 8/9/2026 |
| 3.5.0 | 205 | 8/6/2026 |
| 3.4.0 | 242 | 7/27/2026 |
| 3.3.3 | 275 | 7/16/2026 |
| 3.3.1 | 455 | 7/10/2026 |
| 3.3.0 | 155 | 7/8/2026 |
| 3.2.0 | 246 | 6/29/2026 |
| 3.1.0 | 215 | 6/6/2026 |
| 3.0.1 | 156 | 6/3/2026 |