AxisResult 2.2.0

dotnet add package AxisResult --version 2.2.0
                    
NuGet\Install-Package AxisResult -Version 2.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AxisResult" Version="2.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AxisResult" Version="2.2.0" />
                    
Directory.Packages.props
<PackageReference Include="AxisResult" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AxisResult --version 2.2.0
                    
#r "nuget: AxisResult, 2.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AxisResult@2.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AxisResult&version=2.2.0
                    
Install as a Cake Addin
#tool nuget:?package=AxisResult&version=2.2.0
                    
Install as a Cake Tool

AxisResult β€” Documentation

🌐 PortuguΓͺs (documentaΓ§Γ£o navegΓ‘vel)

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). .Value throws on a failure β†’ prefer the safe deconstruction or Match.
  • Moving between the two: ToAxisResult discards the value; WithValueAsync promotes an AxisResult to AxisResult<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

  1. Errors are values, not exceptions. An operation that can fail says so in its return type.
  2. The type system is the documentation. Task<AxisResult<User>> already tells you everything that can happen.
  3. Composition over ceremony. Small, focused operations that compose.
  4. Fail fast, recover deliberately. Errors propagate on their own; recovery is always explicit.
  5. Exceptions at the boundary, results everywhere else. AxisResult.Try() at infrastructure edges; above that, exception-free.

License

Apache 2.0

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • 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.

Version Downloads Last Updated
2.2.0 637 7/21/2026
2.1.1 459 7/17/2026
2.1.0 453 7/17/2026
2.0.1 463 7/15/2026
2.0.0 469 7/15/2026