AxisResult 2.2.0
dotnet add package AxisResult --version 2.2.0
NuGet\Install-Package AxisResult -Version 2.2.0
<PackageReference Include="AxisResult" Version="2.2.0" />
<PackageVersion Include="AxisResult" Version="2.2.0" />
<PackageReference Include="AxisResult" />
paket add AxisResult --version 2.2.0
#r "nuget: AxisResult, 2.2.0"
#:package AxisResult@2.2.0
#addin nuget:?package=AxisResult&version=2.2.0
#tool nuget:?package=AxisResult&version=2.2.0
AxisResult β Documentation
Railway-Oriented Programming for C# β a zero-dependency Result monad with full async/ValueTask support, typed error categories and monadic composition (Then / Map / Zip).
public Task<AxisResult<AddCellphoneResponse>> HandleAsync(AddCellphoneCommand cmd)
=> personFactory.GetByIdAsync(cmd.PersonId)
.ThenAsync(person => cellphoneMediator.AddAsync(new() { Number = cmd.Number }))
.ThenAsync(response => response.AddCellphoneAsync(cmd.CellphoneId))
.ThenAsync(_ => unitOfWork.SaveChangesAsync())
.MapAsync(_ => new AddCellphoneResponse { CellphoneId = cmd.CellphoneId });
Use this page as a map: read the trunk below (~5 min) and jump straight to the detail of the group you need β without reading hundreds of lines.
The trunk (read first)
Railway in 60 seconds
Imagine your code as a railway with two rails:
Success βββββββββββββββββββββββββββββββββΆ result
β β β
validate fetch save
β β β
Failure βββββββββββββββββββββββββββββββββΆ errors
Each operation either succeeds and stays on the top rail, or fails and drops to the bottom one β skipping everything else. No try/catch, no if (x == null), no mid-handler return. β Railway-Oriented Programming
AxisResult vs AxisResult<T> β "no data" and "with data"
AxisResultβ the outcome of an operation that produces no value: only whether it worked matters (save, delete, validate, verify a password).AxisResult<T>β carries a value along the success rail (fetch an entity, compute a total)..Valuethrows on a failure β prefer the safe deconstruction orMatch.- Moving between the two:
ToAxisResultdiscards the value;WithValueAsyncpromotes anAxisResulttoAxisResult<T>.
Creating results
AxisResult ok = AxisResult.Ok();
AxisResult<int> typed = AxisResult.Ok(42);
AxisResult<int> fail = AxisError.BusinessRule("INSUFFICIENT_STOCK"); // AxisError β failure (implicit)
AxisResult<string> name = "John"; // value β Ok (implicit)
AxisResult<int> parse = AxisResult.Try(() => int.Parse(input)); // exception β AxisResult, only at the edge
AxisResult<string> rop = user.Email.Rop(); // value β Ok, fluent: starts the ROP flow
Error handling
An error is a value (AxisError = Code + Type), not an exception. The 12 categories map to HTTP status codes, and IsTransient/result.IsTransientFailure enable retry. β Errors and types
Task vs ValueTask
When in doubt, use Task. ValueTask only on hot paths that complete synchronously. β Task vs ValueTask
Installation
dotnet add package AxisResult
β Full guide: Getting started
The map (jump to what you need)
| Group | You want to⦠| Detail |
|---|---|---|
Transform Β· Map |
change the value (cannot fail) | map.md |
Chain Β· Then β |
a step that can fail (heart of the library) | then.md |
Ensure Β· Ensure |
validate an invariant inline | ensure.md |
Guard Β· ThenUnless |
run a fallible step only when a condition is false | then-unless.md |
Conditional step Β· ThenWhen |
run a same-type transforming step only when a condition is true | then-when.md |
Exit Β· Match |
collapse the pipeline into a final value | match.md |
Side effects Β· Tap |
observe (log/metric) without changing the rail | tap.md |
Recover Β· Recover |
handle the failure and return to success | recover.md |
Combine Β· Zip |
join different values into a tuple | zip.md |
Aggregate Β· Combine/All |
reduce N results into one | aggregate.md |
Remap errors Β· MapError |
rewrite errors between layers | map-errors.md |
| Cancellation | thread CancellationToken through the chain |
cancellation.md |
Start here: Getting started Β· Railway-Oriented Programming Β· Why AxisResult?
Fundamentals: Errors and types Β· Task vs ValueTask Β· Exceptions at the boundary
Reference & extras: API reference Β· LINQ query syntax Β· Ergonomics
Design principles
- Errors are values, not exceptions. An operation that can fail says so in its return type.
- The type system is the documentation.
Task<AxisResult<User>>already tells you everything that can happen. - Composition over ceremony. Small, focused operations that compose.
- Fail fast, recover deliberately. Errors propagate on their own; recovery is always explicit.
- Exceptions at the boundary, results everywhere else.
AxisResult.Try()at infrastructure edges; above that, exception-free.
License
Apache 2.0
| 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
- No dependencies.
NuGet packages (10)
Showing the top 5 NuGet packages that depend on AxisResult:
| Package | Downloads |
|---|---|
|
AxisMediator.Contracts
Contracts (commands, queries, handlers) shared between AxisMediator and its consumers, with analyzers that enforce them at build time. |
|
|
AxisLogger
Part of the Axis Framework β an opinionated, ports-and-adapters .NET framework. |
|
|
AxisRepository
Part of the Axis Framework β an opinionated, ports-and-adapters .NET framework. |
|
|
AxisCache
Part of the Axis Framework β an opinionated, ports-and-adapters .NET framework. |
|
|
AxisStorage
Part of the Axis Framework β an opinionated, ports-and-adapters .NET framework. |
GitHub repositories
This package is not used by any popular GitHub repositories.