redb.Route.Controllers
2.0.2
Prefix Reserved
dotnet add package redb.Route.Controllers --version 2.0.2
NuGet\Install-Package redb.Route.Controllers -Version 2.0.2
<PackageReference Include="redb.Route.Controllers" Version="2.0.2" />
<PackageVersion Include="redb.Route.Controllers" Version="2.0.2" />
<PackageReference Include="redb.Route.Controllers" />
paket add redb.Route.Controllers --version 2.0.2
#r "nuget: redb.Route.Controllers, 2.0.2"
#:package redb.Route.Controllers@2.0.2
#addin nuget:?package=redb.Route.Controllers&version=2.0.2
#tool nuget:?package=redb.Route.Controllers&version=2.0.2
redb.Route.Controllers
Transport-agnostic controller dispatch for the redb.Route ESB framework.
Provides a RedbController base class, attribute-based routing, parameter binding, and four dispatcher implementations for generic, HTTP, SignalR, and gRPC transports with 13 DSL extension methods. Controllers are transport-unaware — the same controller class works behind any InOut endpoint.
Quick Start
// Define a controller
[Route("orders")]
public class OrdersController : RedbController
{
[HttpGet("{id}")]
public Task<Order> GetOrder(int id)
{
return Task.FromResult(new Order { Id = id, Title = "Sample" });
}
[HttpPost]
public Task CreateOrder([FromBody] Order order)
{
// Access route context and exchange
var ctx = Context;
var exchange = Exchange;
return Task.CompletedTask;
}
}
// Register and dispatch (generic)
var registry = new ControllerRegistry();
registry.RegisterAssembly(typeof(OrdersController).Assembly);
route.From("direct://api")
.RedbController(registry);
// Or single controller shorthand
route.From("direct://api")
.RedbController<OrdersController>();
Architecture
This is not a connector (no IComponent, no URI scheme, no producer/consumer). It is a processing library that provides IProcessor implementations and DSL extension methods. Controllers sit behind direct: or transport endpoints and dispatch based on headers set by the upstream consumer.
HTTP Consumer → [redbHttp.Method, redbHttp.Path] → HttpControllerDispatcher → OrdersController.GetOrder()
SignalR Hub → [redbSignalR.Method] → SignalRControllerDispatcher → ChatController.Send()
gRPC Service → [dispatch-method] → GrpcControllerDispatcher → CalcController.Add()
Any Endpoint → [route.method, route.path] → ControllerDispatcherProcessor → generic dispatch
RedbController Base Class
All controllers inherit from RedbController, which exposes:
| Property | Type | Description |
|---|---|---|
Context |
IRouteContext |
Route context for the current invocation |
Exchange |
IExchange |
Current exchange being processed |
Controllers are instantiated per-request via Activator.CreateInstance(). No DI constructor injection — use Context to access services.
Attributes
Route Attribute
Applied to the controller class. Sets the base path for all actions:
[Route("modules")] // explicit path
public class ModulesController : RedbController { }
// If omitted, defaults to class name minus "Controller" suffix, lowercased:
public class UsersController : RedbController { } // base path: "users"
HTTP Method Attributes
Applied to public methods. Define the HTTP method and optional sub-template:
| Attribute | Method | Example |
|---|---|---|
[HttpGet] |
GET | [HttpGet], [HttpGet("{id}")] |
[HttpPost] |
POST | [HttpPost], [HttpPost("batch")] |
[HttpPut] |
PUT | [HttpPut("{id}")] |
[HttpDelete] |
DELETE | [HttpDelete("{id}")] |
[HttpPatch] |
PATCH | [HttpPatch("{id}")] |
Templates support {param} placeholders that are extracted from the request path and matched to method parameters by name.
Binding Attributes
| Attribute | Source | Example |
|---|---|---|
[FromBody] |
exchange.In.Body |
[FromBody] Order order |
[FromHeader("X-Tenant")] |
exchange.In.Headers["X-Tenant"] |
[FromHeader("X-Tenant")] string tenant |
[FromQuery("page")] |
Query parameter | [FromQuery("page")] int page |
[FromRoute("id")] |
Route template {id} |
[FromRoute("id")] int id |
[FromProperty("user")] |
exchange.Properties["user"] |
[FromProperty("user")] User user |
Implicit binding (no attribute):
CancellationToken→CancellationToken.None- Parameter name matches a route template
{param}→ bound from route - Complex type → deserialized from body
- Simple type with default value → uses default
Dispatchers
ControllerDispatcherProcessor (Generic)
Reads route.path and route.method headers. Works with any transport.
// Set headers before dispatch
exchange.In.Headers["route.path"] = "orders/42";
exchange.In.Headers["route.method"] = "GET";
// DSL
route.From("direct://api").RedbController(registry);
route.From("direct://api").RedbController<OrdersController>();
route.From("direct://api").RedbController<OrdersController>("GetOrder"); // direct method call
HttpControllerDispatcher
Reads redbHttp.Method and redbHttp.Path headers (set automatically by the HTTP consumer). Also merges redbHttp.RouteParam.* and reads redbHttp.QueryParam.* for parameter binding.
route.From("http://0.0.0.0:8080/api")
.RedbHttpController(registry);
route.From("http://0.0.0.0:8080/api")
.RedbHttpController<OrdersController>();
SignalRControllerDispatcher
Reads redbSignalR.Method header. Parameters are resolved positionally from the exchange body (as sent by the SignalR client).
route.From("signalr://bridge")
.RedbSignalRController<ChatController>();
// Multiple controllers
route.From("signalr://bridge")
.RedbSignalRController(typeof(ChatController), typeof(NotificationController));
// Method resolution: "Send" or "Chat.Send" (qualified)
GrpcControllerDispatcher
Reads dispatch-method header from gRPC metadata. Body is treated as JSON — single value or array of positional arguments.
route.From("grpc://0.0.0.0:5000")
.RedbGrpcController<CalcController>();
// Multiple controllers
route.From("grpc://0.0.0.0:5000")
.RedbGrpcController(typeof(CalcController), typeof(DataController));
ControllerRegistry
Builds a route lookup table by scanning assemblies or registering individual controller types:
var registry = new ControllerRegistry();
// Scan entire assembly
int count = registry.RegisterAssembly(typeof(OrdersController).Assembly);
// Or register individual controllers
registry.RegisterController(typeof(OrdersController));
registry.RegisterController(typeof(UsersController));
// Resolve manually
var action = registry.Resolve(HttpMethodType.Get, "orders/42", out var routeParams);
// action.ControllerType = typeof(OrdersController)
// action.Method = GetOrder
// routeParams["id"] = "42"
Response Conventions
| Scenario | status.code |
Body |
|---|---|---|
| Method returns a value | 200 |
Return value (JSON-serialized for HTTP/gRPC) |
Method returns null or Task (void) |
204 |
— |
| Missing headers | 400 |
ControllerErrorResponse |
| No matching action | 404 |
ControllerErrorResponse |
| Exception during invocation | 500 |
ControllerErrorResponse |
// Error response model
public sealed class ControllerErrorResponse
{
public string Error { get; init; } // e.g. "NotFound", "BadRequest", "InternalError"
public string Message { get; init; } // Human-readable description
public int StatusCode { get; init; } // HTTP status code
}
DSL Extension Methods
All methods are on IRouteDefinition:
| Method | Dispatcher | Headers Read |
|---|---|---|
RedbController(registry) |
Generic | route.path, route.method |
RedbController<T>() |
Generic | route.path, route.method |
RedbController<T>(methodName) |
Direct invoke | — |
RedbController(registry, ctrlName, methodName) |
Direct invoke | — |
RedbController(registry, ctrlExpr, methodExpr) |
Dynamic | Exchange-dependent |
RedbHttpController(registry) |
HTTP | redbHttp.Method, redbHttp.Path |
RedbHttpController<T>() |
HTTP | redbHttp.Method, redbHttp.Path |
RedbSignalRController<T>() |
SignalR | redbSignalR.Method |
RedbSignalRController(types) |
SignalR | redbSignalR.Method |
RedbSignalRController(registry) |
SignalR | redbSignalR.Method |
RedbGrpcController<T>() |
gRPC | dispatch-method |
RedbGrpcController(types) |
gRPC | dispatch-method |
RedbGrpcController(registry) |
gRPC | dispatch-method |
Requirements
- .NET 8.0 / 9.0 / 10.0
redb.Route(core) — no external dependencies
| 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.Route (>= 2.0.2)
-
net8.0
- redb.Route (>= 2.0.2)
-
net9.0
- redb.Route (>= 2.0.2)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on redb.Route.Controllers:
| Package | Downloads |
|---|---|
|
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.