Trellis.Core
3.0.0-alpha.505
dotnet add package Trellis.Core --version 3.0.0-alpha.505
NuGet\Install-Package Trellis.Core -Version 3.0.0-alpha.505
<PackageReference Include="Trellis.Core" Version="3.0.0-alpha.505" />
<PackageVersion Include="Trellis.Core" Version="3.0.0-alpha.505" />
<PackageReference Include="Trellis.Core" />
paket add Trellis.Core --version 3.0.0-alpha.505
#r "nuget: Trellis.Core, 3.0.0-alpha.505"
#:package Trellis.Core@3.0.0-alpha.505
#addin nuget:?package=Trellis.Core&version=3.0.0-alpha.505&prerelease
#tool nuget:?package=Trellis.Core&version=3.0.0-alpha.505&prerelease
Trellis.Core
Railway-oriented error handling for .NET with Result<T>, Maybe<T>, and typed errors.
Installation
dotnet add package Trellis.Core
Quick Example
using Trellis;
Result<string> email = Result.Ok("ada@example.com")
.Ensure(value => value.Contains('@'),
Error.InvalidInput.ForField("email", ValidationCodes.StringEmail, "Email is invalid."))
.Map(value => value.Trim().ToLowerInvariant());
Key Features
- Compose success and failure paths with
Bind,Map,Tap, andEnsure. - Model optional data with
Maybe<T>instead ofnull. - Return typed errors that map cleanly to APIs, logs, and tests.
- Use
AsTask()/AsValueTask()to return synchronousResultchains from async-shaped APIs. - Build resource-aware HTTP errors tersely with
ResourceRef.For<TResource>(id). - Define custom
Required*<TSelf>value objects with source-generated parsing, JSON conversion, and tracing support. - Persist staged state alongside a failure with
Result.FailAfterCommit<T>(error)— opt-in for background-worker handlers that need a permanent-failure transition to commit even though the handler returns a failed result. - Classify
Errorvalues intoTransient/Permanent/FailFastretry buckets witherror.Classify()/error.IsTransient()/error.GetRetryAdvice()— transport-neutral helpers for worker, consumer, and outbound-gateway retry loops. - Validate pagination controls with
PageRequest, encode typed continuation state withICursorCodec<TState>, and return immutablePage<T>responses.
Typed pagination
Result<PageRequest> request = PageRequest.TryCreate(cursor, limit);
var codec = CursorCodec.Composite<DateTimeOffset, Guid>();
Result<Maybe<(DateTimeOffset Primary, Guid Secondary)>> boundary =
request.Bind(pageRequest => pageRequest.Decode(codec));
Only a missing cursor means the first page; empty/whitespace tokens fail. A missing
limit defaults to 50, zero/negative limits fail, and values above the default cap
of 100 clamp while preserving the requested limit. Pass
policy: PageSizeLimitPolicy.Reject to reject above-cap requests.
PageSize.FromRequested is a trusted throwing convenience, not a raw-input parser.
Cursor, PageSize, and Page<T> are sealed record classes, not defaultable
struct values. PageBuilder.FromOverFetch(rows, size, last => codec.Encode(state))
only assembles an already ordered/sought batch; its encoder runs on the last
retained item only when another row exists. For provider-owned continuation
tokens, construct Page<T> directly. Page<T>.Map preserves both cursors and limits.
Use CursorCodec.Map for named validated state/context or Create for an explicit
serializer/parser. Built-in codecs are versioned, round-trip-checked, limited to
1,024 encoded characters, and unsigned. Old unversioned tokens are rejected.
Storage queries, authorization, signing, and computed-search algorithms remain
application-owned.
Result<T> is not directly JSON-serializable
Result<T> carries a default [JsonConverter] that throws NotSupportedException on direct JsonSerializer.Serialize / Deserialize. Returning a raw Result<T> from a controller would otherwise hand MVC a domain disposition whose public JSON surface is only status/error metadata such as {"IsSuccess": true, "IsFailure": false, "Error": null}; the success value stays private, and Error.* cases still get no HTTP status-code mapping (an Error.NotFound would render as 200 OK instead of 404). The throw fires at the first request with an actionable message. Fix paths:
- HTTP — call
.ToHttpResponse()(Trellis.Asp). The returnedMicrosoft.AspNetCore.Http.IResultwrites the body itself; the struct never reaches STJ. - Non-HTTP — unwrap with
Match/TryGetValuebefore serialization. - Genuinely need raw JSON (logging, IPC) — register a converter (or a
JsonConverterFactory) inJsonSerializerOptions.Converters; option-registered converters take precedence over the type's[JsonConverter]attribute. The override must match the declared static type:JsonConverter<Result<T>>covers onlyResult<T>-declared values;IResult<T>-declared values needJsonConverter<IResult<T>>;IResult-declared values needJsonConverter<IResult>. Use aJsonConverterFactoryto cover multiple shapes at once.
Documentation
Part of Trellis
This package is part of the Trellis framework.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- OpenTelemetry.Api (>= 1.18.0)
NuGet packages (16)
Showing the top 5 NuGet packages that depend on Trellis.Core:
| Package | Downloads |
|---|---|
|
Trellis.Authorization
Lightweight authorization primitives for Trellis. Provides Actor, IActorProvider, IAuthorize, IAuthorizeResource of TResource, IResourceLoader, and ResourceLoaderById types that integrate with the Trellis Result type system. No dependency on any mediator or web framework. |
|
|
Trellis.Asp
ASP.NET Core integration for Trellis. Result-to-HTTP response mapping, scalar value validation, JSON converters (with bundled AOT source generator), and ASP.NET actor providers (Claims, Entra, Easy Auth, Development) for Trellis.Authorization. |
|
|
Trellis.Primitives
Infrastructure and ready-to-use implementations for primitive value objects in Domain-Driven Design. Includes base classes (RequiredString, RequiredGuid) with source generation, plus EmailAddress with RFC 5322 validation. Eliminates primitive obsession with strongly-typed domain primitives. |
|
|
Trellis.Mediator
Result-aware pipeline behaviors for martinothamar/Mediator. Provides validation, authorization, logging, tracing, and exception handling behaviors that understand Trellis Result types and short-circuit correctly. |
|
|
Trellis.Testing
FluentAssertions extensions and test doubles for Trellis - assert Result, Maybe, and Error types with readable fluent syntax |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0-alpha.505 | 180 | 9/13/2026 |
| 3.0.0-alpha.495 | 355 | 8/24/2026 |
| 3.0.0-alpha.458 | 349 | 8/19/2026 |
| 3.0.0-alpha.455 | 377 | 8/19/2026 |
| 3.0.0-alpha.449 | 197 | 8/18/2026 |
| 3.0.0-alpha.447 | 196 | 8/18/2026 |
| 3.0.0-alpha.432 | 236 | 7/6/2026 |
| 3.0.0-alpha.428 | 207 | 7/3/2026 |
| 3.0.0-alpha.425 | 241 | 6/27/2026 |
| 3.0.0-alpha.419 | 164 | 6/24/2026 |
| 3.0.0-alpha.418 | 332 | 6/23/2026 |
| 3.0.0-alpha.417 | 152 | 6/23/2026 |
| 3.0.0-alpha.397 | 236 | 6/18/2026 |
| 3.0.0-alpha.396 | 142 | 6/18/2026 |
| 3.0.0-alpha.394 | 159 | 6/18/2026 |
| 3.0.0-alpha.385 | 143 | 6/15/2026 |
| 3.0.0-alpha.382 | 151 | 6/12/2026 |
| 3.0.0-alpha.372 | 141 | 6/10/2026 |
| 3.0.0-alpha.360 | 181 | 6/7/2026 |
| 3.0.0-alpha.342 | 181 | 6/5/2026 |