Table of Contents

Namespace Trellis

Classes

AggregateETagExtensions

Extension methods for ETag-based optimistic concurrency validation on aggregate results. Two modes are available — the service owner chooses which to use:

Aggregate<TId>

Base class for aggregate roots in Domain-Driven Design. An aggregate is a cluster of domain objects (entities and value objects) that form a consistency boundary. The aggregate root is the only entry point for modifications and ensures all invariants within the boundary are maintained.

AsUnitExtensions

Asynchronous bridges that discard a result's success value and project to a no-payload Result<Unit>. Pairs with AsUnit() for sync receivers.

AuthChallenge

Represents a single HTTP authentication challenge (RFC 9110 §11.6.1) carried by Error.Unauthorized. Multiple challenges may be combined to round-trip the full WWW-Authenticate header.

BindExtensions

Provides extension methods for binding (chaining) operations over Result values.

BindExtensionsAsync

Provides asynchronous extension methods for binding (chaining) operations over Result values.

BindZipExtensions

Extension methods that bind a function to a Result and zip the original value with the new value into a tuple. Enables sequential accumulation of values through a pipeline.

BindZipExtensionsAsync

Async BindZip extensions where both input and function are async (Task).

CheckExtensions

Provides extension methods for running validation functions on Result values while preserving the original value on success. If the check fails, its failure is returned.

CheckExtensionsAsync

Async Check extensions where BOTH input and check function are async (Task).

CheckIfExtensions

Provides conditional check extension methods for Result values. The check function is only invoked when the condition or predicate is true; otherwise the original result passes through unchanged.

CheckIfExtensionsAsync

Async CheckIf extensions where BOTH input and check function are async (Task).

CombineErrorExtensions

Combines two Error values into one. Two Error.UnprocessableContent values merge their field/rule violations. Otherwise the two errors are flattened into an Error.Aggregate.

CombineExtensions

Combines two or more Result<TValue> into one tuple containing all the Results.

CombineExtensionsAsync

Combines two or more Result<TValue> into one tuple containing all the Results.

DiscardExtensions

Provides extension methods for explicitly discarding a Result value. Use when the outcome is intentionally ignored (e.g., best-effort operations). This is the idiomatic alternative to _ = result; and suppresses TRLS001 without requiring pragma directives.

DiscardTaskExtensions

Provides async extension methods for explicitly discarding a Task-wrapped Result value.

DiscardValueTaskExtensions

Provides async extension methods for explicitly discarding a ValueTask-wrapped Result value.

EnsureAllExtensions

Provides extension methods for ensuring multiple conditions on Result values simultaneously. Unlike Ensure<TValue>(Result<TValue>, Func<TValue, bool>, Error) which short-circuits on the first failure, EnsureAll runs ALL checks and accumulates errors into a single combined error.

EnsureAllExtensionsAsync

Provides asynchronous extension methods for EnsureAll validation accumulation on Result values.

EnsureExtensions

Provides extension methods for ensuring conditions on Result values. If conditions fail, the result is converted to a failure with the specified error.

EnsureExtensionsAsync

Async Ensure extensions where BOTH input and predicates are async (Task).

EntityTagValue

Represents an RFC 9110 §8.8.1 entity tag (ETag) value with explicit weak/strong semantics.

Entity<TId>

Base class for entities in Domain-Driven Design. An entity is a domain object defined by its identity rather than its attributes. Two entities with different attributes but the same ID are considered equal.

EnumValueAttribute

Specifies the canonical symbolic value for a RequiredEnum<TSelf> member.

EquatableArray

Non-generic factory helpers for EquatableArray<T> that allow type inference.

Error

Closed discriminated union of error values. Each case is a nested sealed record that mirrors a status from the IANA HTTP Status Code Registry (RFC 9110, RFC 6585) and carries a strongly-typed payload describing what went wrong.

Error.Aggregate

Composition of multiple independent errors. Used when several failures occur together (e.g. parallel operations, batch validation). On the wire this typically renders as a problem-details extensions.errors array; 207 Multi-Status is reserved for explicit batch endpoints.

Error.BadRequest

HTTP 400 — the request is syntactically or semantically malformed.

Error.Conflict

HTTP 409 — the request conflicts with the current state of the resource.

Error.ContentTooLarge

HTTP 413 — the request payload exceeds size limits.

Error.Forbidden

HTTP 403 — authorization policy refused the request.

Error.Gone

HTTP 410 — the resource is permanently gone.

Error.InternalServerError

HTTP 500 — an unhandled server-side fault occurred.

Error.MethodNotAllowed

HTTP 405 — the HTTP method is not supported by the target resource.

Error.NotAcceptable

HTTP 406 — none of the available representations are acceptable to the client.

Error.NotFound

HTTP 404 — the requested resource does not exist.

Error.NotImplemented

HTTP 501 — the requested feature is not implemented.

Error.PreconditionFailed

HTTP 412 — a request precondition (e.g. If-Match) failed.

Error.PreconditionRequired

HTTP 428 — the resource requires a precondition that the request did not include.

Error.RangeNotSatisfiable

HTTP 416 — the requested byte range cannot be satisfied.

Error.ServiceUnavailable

HTTP 503 — the server is temporarily unable to handle the request.

Error.TooManyRequests

HTTP 429 — the client has exceeded a rate limit.

Error.Unauthorized

HTTP 401 — authentication is required or has failed.

Error.Unexpected

HTTP 500 — a "shouldn't happen" condition. Used for default-initialized Result/Result<TValue>, exhausted match arms, or other internal invariant violations whose root cause is a programming error rather than a documented server-side fault.

Error.UnprocessableContent

HTTP 422 — the request was well-formed but the content failed semantic validation.

Error.UnsupportedMediaType

HTTP 415 — the request's media type is not supported.

FieldViolation

Describes a validation failure attached to a specific field of an input document. Used inside Error.UnprocessableContent.

GetValueOrDefaultExtensions

Terminal extraction methods for Result values.

MapExtensions

Provides extension methods for mapping (transforming) values inside Result objects.

MapExtensionsAsync

Provides asynchronous extension methods for mapping (transforming) values inside Result objects.

MapIfExtensions

Conditionally transforms the value inside a Result when a condition or predicate is met.

MapOnFailureExtensions

Provides extension methods for transforming errors in failed Results while leaving successful Results unchanged.

MatchExtensions

Pattern matching helpers (Match / Switch) for Result.

MatchExtensionsAsync

Asynchronous pattern matching helpers for Result.

Maybe

Contains static methods to create a Maybe<T> object.

MaybeChooseExtensions

Extension methods for filtering and unwrapping Maybe<T> collections.

MaybeCollectionExtensions

Extension methods for safely querying collections, returning Maybe<T> instead of throwing.

MaybeExtensions

Provides extension methods for converting Maybe<T> instances to Result<TValue> objects and for wrapping values in a Result<TValue>.

MaybeExtensionsAsync

Asynchronous MatchAsync extension methods for Task<TResult> and ValueTask<TResult> of Maybe<T>.

MaybeInvariant

Provides static methods for validating invariants across multiple Maybe<T> values. These methods express relationships between correlated optional values — such as "all or none", "if A then B", or "exactly one" — and return Result<TValue> with field-level Error.UnprocessableContent details when the invariant is violated.

MaybeLinqExtensions

Provides LINQ query expression support for Maybe types, enabling C# query syntax for optional value composition.

NullableExtensions

Extension methods for converting nullable values to Result types. Provides a convenient way to handle null checking with Railway Oriented Programming.

NullableExtensionsAsync

Asynchronous extension methods for converting nullable values to Result types.

Page

Non-generic factory companion for Page<T>. Mirrors the Result / Result<T> split: factory methods live on the non-generic type to keep generic-type surface minimal (CA1000) and to allow type inference at the call site.

ParsableJsonConverter<T>

A JSON converter for value objects that implement IParsable<TSelf>. Enables automatic serialization and deserialization of parsable value objects in ASP.NET Core APIs and System.Text.Json scenarios.

PrimitiveValueObjectTrace

Provides OpenTelemetry activity tracing for Trellis primitive value object operations. Enables monitoring and diagnostics of value object creation, validation, and parsing activities.

PrimitiveValueObjectTraceProviderBuilderExtensions

Provides extension methods for configuring OpenTelemetry tracing for Trellis primitive value objects.

RailwayTrackAttribute

Indicates which railway track an operation executes on. This metadata can be used by IDE extensions, analyzers, and documentation generators.

RangeAttribute

Specifies the minimum and maximum allowed values for numeric value objects (RequiredInt<TSelf>, RequiredDecimal<TSelf>, RequiredLong<TSelf>).

RecoverExtensions

Provides extension methods for recovering from failures with a fallback value. Unlike RecoverOnFailureExtensions which requires a function returning a Result, Recover takes a simple fallback value and always produces a success.

RecoverExtensionsAsync

Provides asynchronous extension methods for recovering from failures with a fallback value.

RecoverOnFailureExtensions

Provides extension methods for recovering from failed results by executing fallback operations.

RecoverOnFailureExtensionsAsync

Provides asynchronous extension methods for recovering from failed results.

RepresentationMetadata

Carries HTTP representation metadata (RFC 9110 §8) through Trellis response mappers. Used to emit ETag, Last-Modified, Vary, Content-Language, Content-Location, and Accept-Ranges response headers consistently across MVC and Minimal API responses (200, 201, 206, 304).

RepresentationMetadata.Builder

Fluent builder for constructing RepresentationMetadata instances.

RequiredBool<TSelf>

Base class for creating strongly-typed boolean value objects that distinguish between false (an explicit value) and null/missing (no value provided).

RequiredDateTime<TSelf>

Base class for creating strongly-typed DateTime value objects that prevent primitive obsession for dates. Rejects MinValue as the "empty" equivalent.

RequiredDecimal<TSelf>

Base class for creating strongly-typed decimal value objects that must be explicitly provided. Provides a foundation for monetary amounts, percentages, and other domain concepts represented by decimals.

RequiredEnumJsonConverter<TRequiredEnum>

JSON converter for RequiredEnum<TSelf> types. Serializes to the string value and deserializes from string value.

RequiredEnum<TSelf>

Base class for creating strongly-typed, behavior-rich enumeration value objects. Enum value objects are a DDD pattern that replaces C# enums with full-featured classes.

RequiredGuid<TSelf>

Base class for creating strongly-typed GUID value objects that cannot have the default (empty) GUID value. Provides a foundation for entity identifiers and other domain concepts represented by GUIDs.

RequiredInt<TSelf>

Base class for creating strongly-typed integer value objects that must be explicitly provided. Provides a foundation for entity identifiers, counts, and other domain concepts represented by integers.

RequiredLong<TSelf>

Base class for creating strongly-typed long integer value objects. Provides a foundation for large identifiers, sequence numbers, and other domain concepts represented by long integers.

RequiredString<TSelf>

Base class for creating strongly-typed string value objects that cannot be null or empty. Provides a foundation for domain primitives like names, descriptions, codes, and other textual concepts.

Result

Static factory and helper methods for constructing Result<TValue> values.

ResultDebugExtensions

Debug extension methods for inspecting Result values during development. These methods execute only in DEBUG builds and become no-ops in RELEASE builds (with zero overhead).

ResultDebugExtensionsAsync

Debug-only async extension methods for inspecting Result values during development. These methods are only available in DEBUG builds and are automatically excluded from RELEASE builds. Debug information is written to dedicated Activity spans for OpenTelemetry compatibility.

ResultDebugSettings

Controls runtime behavior of ResultDebugExtensions methods (Debug, DebugDetailed, DebugWithStack, DebugOnSuccess, DebugOnFailure).

ResultLinqExtensions

Provides LINQ query expression support for Result types, enabling C# query syntax for functional operations.

ResultLinqExtensionsTaskAsync

Provides LINQ query expression support for Task<TResult> of Result<TValue>, enabling C# query syntax over fully asynchronous Result-returning operations.

ResultLinqExtensionsTaskLeftAsync

Async LINQ SelectMany overload where the source is a Task<TResult> of Result<TValue> and the collection selector is synchronous.

ResultLinqExtensionsTaskRightAsync

Async LINQ SelectMany overload where the source is a synchronous Result<TValue> and the collection selector returns a Task<TResult> of Result<TValue>.

ResultLinqExtensionsValueTaskAsync

Provides LINQ query expression support for ValueTask<TResult> of Result<TValue>, enabling C# query syntax over fully asynchronous Result-returning operations that may complete synchronously.

ResultLinqExtensionsValueTaskLeftAsync

Async LINQ SelectMany overload where the source is a ValueTask<TResult> of Result<TValue> and the collection selector is synchronous.

ResultLinqExtensionsValueTaskRightAsync

Async LINQ SelectMany overload where the source is a synchronous Result<TValue> and the collection selector returns a ValueTask<TResult> of Result<TValue>.

ResultTaskAdapterExtensions

Provides adapters that wrap already-computed Result<TValue> values in completed task-like carriers.

ResultsTraceProviderBuilderExtensions

Extension methods for configuring OpenTelemetry tracing for Railway Oriented Programming operations.

RetryAfterValue

Represents an RFC 9110 §10.2.3 Retry-After value, which can be either a delay in seconds or an absolute HTTP-date indicating when the client may retry.

RuleViolation

Describes a global or multi-field business-rule failure attached to a Error.UnprocessableContent. Use this for invariant violations that are not bound to a single field (e.g. "order_must_have_items", "passwords_must_match", "cancel_after_ship").

ScalarValueObject<TSelf, T>

Base class for value objects that wrap a single scalar value. Provides a strongly-typed wrapper around primitive types with domain semantics.

SequenceAllExtensions

Accumulating-error counterpart to Sequence<T>(IEnumerable<Result<T>>). Runs through every item; folds failures via the existing Combine(Error?, Error) extension so two Error.UnprocessableContent failures merge their fields/rules and heterogeneous failures flatten into Error.Aggregate.

Specification<T>

Base class for the Specification pattern. Encapsulates a business rule as a composable, storage-agnostic expression tree.

StringExtensions

String manipulation helpers for value object field name normalization.

StringLengthAttribute

Specifies the minimum and maximum length of characters that are allowed in a RequiredString<TSelf>-derived value object.

TapExtensions

Provides extension methods for executing side effects on successful Results without changing the Result.

TapExtensionsAsync

Provides asynchronous extension methods for executing side effects on successful Results without changing the Result.

TapOnFailureExtensions

Provides extension methods for executing side effects on failed Results without changing the Result.

TapOnFailureExtensionsAsync

Provides asynchronous extension methods for executing side effects on failed Results without changing the Result.

ToMaybeExtensions

Provides extension methods for converting Result{T} to Maybe{T}. Success results become Some(value), failure results become None.

ToMaybeExtensionsAsync

Provides asynchronous extension methods for converting Result{T} to Maybe{T}.

TraverseAllExtensions

Accumulating-error counterpart to Traverse<TIn, TOut>(IEnumerable<TIn>, Func<TIn, Result<TOut>>). Runs the selector over every item (no short-circuit) and folds failures via the existing Combine(Error?, Error) extension. Useful for form-style validation where every error matters, not just the first one encountered.

TraverseExtensions

Transforms a collection of items into a Result containing a collection, short-circuiting on the first failure. Useful for processing collections where each item can fail independently.

TrellisJsonValidationException

Thrown by Trellis JSON converters when a structured value object's invariants are violated during deserialization (e.g., Money's amount/currency rules).

ValueObject

Base class for value objects in Domain-Driven Design. A value object represents a descriptive aspect of the domain with no conceptual identity. Value objects are immutable, defined by their attributes, and support structural equality.

WhenExtensions

Conditionally executes an operation based on a predicate, maintaining the railway. Useful for executing operations only when certain conditions are met without breaking the Result chain.

WhenExtensionsAsync

Asynchronous conditional execution operations for Result.

WriteOutcome<T>

Represents the outcome of a write operation (create / replace / accept-for-async) returned by Application-layer repositories. The case selected describes what happened in transport-agnostic terms; transport adapters (e.g. Trellis.Asp) translate each case to a protocol-specific response (HTTP status code + headers, gRPC status, queue ack envelope, etc.).

WriteOutcome<T>.Accepted

The write was accepted for asynchronous processing and a status body is returned. Transports as HTTP 202 Accepted.

WriteOutcome<T>.AcceptedNoContent

The write was accepted for asynchronous processing with no status body. Transports as HTTP 202 Accepted.

WriteOutcome<T>.Created

A new resource was created. Transports as HTTP 201 Created.

WriteOutcome<T>.Updated

An existing resource was replaced/updated and the new representation is returned. Transports as HTTP 200 OK.

WriteOutcome<T>.UpdatedNoContent

An existing resource was replaced/updated and no body is returned. Transports as HTTP 204 No Content.

Structs

Cursor

Opaque pagination cursor exchanged between server and client. Servers MUST treat the Token contents as their own private encoding; clients MUST treat it as a black box and only echo it back on the next request.

EquatableArray<T>

Wraps an ImmutableArray<T> to provide structural (sequence) equality.

InputPointer

A pointer into a structured input document, expressed as an RFC 6901 JSON Pointer. Used by validation errors to identify the location of an offending value.

Maybe<T>

Represents domain-level optionality — a value that was either provided or intentionally omitted. Unlike Nullable<T> (value types only) or T? (annotation only for reference types), Maybe<T> is a real generic type that works uniformly with both value and reference types and composes with Result<TValue> pipelines.

Page<T>

A single page of items from a paginated collection together with the cursors needed to fetch adjacent pages. The canonical Trellis primitive for server-driven pagination.

ResourceRef

Identifies a resource by its type and optional identifier. Used as the typed payload for resource-oriented errors such as Error.NotFound, Error.Conflict, Error.Gone, and Error.PreconditionFailed.

Result<TValue>

Represents either a successful computation (with a value) or a failure (with an Error).

Unit

Sentinel type representing the absence of a meaningful value. Used as the type parameter for no-payload results: Result<Unit> represents an operation that either succeeds without producing a value or fails with an Error.

Interfaces

IAggregate

Defines the contract for an aggregate root in Domain-Driven Design. An aggregate is a cluster of domain objects that can be treated as a single unit for data changes.

IDomainEvent

Represents a domain event - a record of something significant that happened in the business domain. Domain events capture state changes and business occurrences that domain experts care about.

IEntity

Non-generic interface for all entities in Domain-Driven Design. Provides automatic timestamp tracking — CreatedAt records when the entity was first persisted, and LastModified tracks the most recent change.

IFailureFactory<TSelf>

Enables construction of a failure result of the implementing type from an Error. Implemented by Result<TValue> to support generic pipeline behaviors that need to construct failure results without knowing the inner type parameter.

IFormattableScalarValue<TSelf, TPrimitive>

Extended interface for scalar value objects that support culture-sensitive string parsing. Use for numeric and date types where IFormatProvider matters for parsing.

IResult

Non-generic base interface for result types, exposing success/failure state and error information.

IResult<TValue>

Generic interface for result types, providing typed access to the success value.

IScalarValue<TSelf, TPrimitive>

Interface for scalar value objects that can be created with validation. Enables automatic ASP.NET Core model binding and JSON serialization.

Enums

PreconditionKind

Identifies which conditional precondition was the subject of a Error.PreconditionFailed or Error.PreconditionRequired error.

TrackBehavior

Defines which railway track an operation runs on in Railway-Oriented Programming.