Resrcify.SharedKernel.Results 4.4.0

dotnet add package Resrcify.SharedKernel.Results --version 4.4.0
                    
NuGet\Install-Package Resrcify.SharedKernel.Results -Version 4.4.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="Resrcify.SharedKernel.Results" Version="4.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Resrcify.SharedKernel.Results" Version="4.4.0" />
                    
Directory.Packages.props
<PackageReference Include="Resrcify.SharedKernel.Results" />
                    
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 Resrcify.SharedKernel.Results --version 4.4.0
                    
#r "nuget: Resrcify.SharedKernel.Results, 4.4.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 Resrcify.SharedKernel.Results@4.4.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=Resrcify.SharedKernel.Results&version=4.4.0
                    
Install as a Cake Addin
#tool nuget:?package=Resrcify.SharedKernel.Results&version=4.4.0
                    
Install as a Cake Tool

Resrcify.SharedKernel.Results

Resrcify.SharedKernel.Results provides a consistent Result pattern for success/failure flows, typed errors, and functional-style composition.

Table of Contents

What you get

  • Core primitives in Primitives/:
    • Result
    • Result<TValue>
    • Error
    • ErrorType, with IsTransient(): Failure, ExternalFailure, Timeout and RateLimit may pass next time; NotFound, Validation, Conflict, Unauthorized, Forbidden and Unprocessable (well formed, but it breaks a rule of the operation: HTTP 422) are about the request (another try fails the same way). ErrorTypeJsonConverter reads a type this version doesn't know as Failure, so a newer service's errors stay readable. The message bus retries by it, the mediator's logging picks its level by it.
  • Factory and composition helpers:
    • Success(...), Failure(...), Create(...)
    • Combine(...)
    • Map(...), Bind(...), Tap(...), Ensure(...), Match(...)
  • Sync and async extension methods for fluent pipelines.
  • ErrorCodes: the code of every error SharedKernel returns or answers with (ErrorCodes.Http.Unreachable, ErrorCodes.Persistence.Concurrency, ErrorCodes.Request.Unhandled, ...), so a service matches Error.Code without a string of its own.
  • ErrorTypes.FromHttpStatus(int) / ToHttpStatus(ErrorType): the one mapping between an error type and an HTTP status (the Web package answers and reads responses by it).
  • Diagnostics/LoggedExceptions: the convention that logs an exception at Error once across the packages that see it.
  • Diagnostics/TransientFailureException and Diagnostics/TransientFailures: SharedKernel's one rule for whether an exception is transient (IsTransient(exception)), and result.ThrowIfTransient() to turn a transient failed result into an exception where a result can't be returned (an outbox handler, a job).

Prerequisites

  • .NET 10 SDK.

Install

Option A: Project reference

<ProjectReference Include="..\path\to\Resrcify.SharedKernel.Results.csproj" />

Option B: NuGet package

<PackageReference Include="Resrcify.SharedKernel.Results" Version="<latest>" />

CLI:

dotnet add package Resrcify.SharedKernel.Results

Quick Start

using Resrcify.SharedKernel.Results.Primitives;

public static Result<UserDto> GetUser(
    string userId)
{
    if (string.IsNullOrWhiteSpace(userId))
    {
        return Error.Validation(
            "User.InvalidId",
            "User id cannot be empty.");
    }

    UserDto? user = FindUser(userId);

    return user is null
        ? Error.NotFound("User.NotFound", $"User '{userId}' was not found.")
        : Result.Success(user);
}

Usage guide

Basic result flow

Result<UserDto> result = GetUser(userId);

if (result.IsSuccess)
{
    return Result.Success(result.Value);
}

foreach (Error error in result.Errors)
{
    logger.LogWarning("{Code}: {Message}", error.Code, error.Message);
}

return Result.Failure<UserDto>(result.Errors);

Combining results

Result<UserDto> user = GetUser(userId);
Result<List<OrderDto>> orders = GetOrders(userId);

Result<UserProfileDto> profile = Result.Combine(user, orders)
    .Map(tuple => new UserProfileDto(tuple.Item1, tuple.Item2));

Functional chaining

Result<UserProfileDto> profile = Result.Combine(user, orders)
    .Map(tuple => new UserProfileDto(tuple.Item1, tuple.Item2))
    .Ensure(
        value => value.Orders.Count > 0,
        Error.Validation("Profile.EmptyOrders", "Orders cannot be empty."))
    .Tap(value => audit.Log("profile-created", value.User.Id));

Logging an exception once

An exception on its way out of a request passes several places that log it: the mediator's behaviors, then the Web package's exception handler. They follow one convention, so it is logged at Error, with its stack, once: the first to see it claims it, which marks it in Exception.Data under LoggedExceptions.DataKey ("Resrcify.SharedKernel.Logged", set to true); the others find the mark and log a Debug line without the stack. Code of a service's own that logs and rethrows can join in:

catch (Exception exception)
{
    if (LoggedExceptions.Claim(exception))
        logger.LogError(exception, "Importing {File} failed", file);
    else
        logger.LogDebug("Importing {File} failed: {Exception}", file, exception.GetType().Name);
    throw;
}

An exception whose Data is read-only can't be marked: everyone logs it at Error, as before.

Transient failures

TransientFailures.IsTransient(exception) is the rule every package judges an exception by (the outbox's tries, the level the mediator's behaviors, the jobs and the message bus log it at): the exception or any of its causes (InnerException, every one of an AggregateException's) is a TransientFailureException, a TimeoutException, an OperationCanceledException (a handler's own: the callers rule out their shutdown first), a DbException with IsTransient, or an HttpRequestException without a status or with a transient one (ErrorTypes.FromHttpStatus: 408, 429, 5xx). Packages and services add to it with an ITransientFailureRule (Abstractions, services.AddTransientFailureRule(...)); the ITransientFailureClassifier in the container ORs them.

A domain event handler (or a job) that gets a failed result it can't return throws it when another try may pass:

var player = await swgohApi.GetPlayerAsync(allyCode, cancellationToken)
    .ThrowIfTransient();   // SwgohApi unreachable: the outbox tries the event again later, logged at Warning
if (player.IsFailure)
    return;                // a definite answer (no such player): nothing to retry

ThrowIfTransient() (on Result, Result<T>, Task<Result> and Task<Result<T>>) throws a TransientFailureException holding the result's errors when any of them is transient (Error.IsTransient()), and returns the result otherwise. The exception's Errors travel: the message bus shows them as the reason a message failed, a rate-limited queue answers its requester with them, and the Web package's exception handler answers a request with their problem details.

Common issues

  • If .Value throws, check IsSuccess first.
  • If combined results lose detail, ensure source errors use meaningful codes/messages.
  • If async chains are hard to read, split into intermediate Result<T> values for clarity.

Sample project

See samples/Resrcify.SharedKernel.WebApiExample for end-to-end usage with messaging, repository, and web layers.

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 (8)

Showing the top 5 NuGet packages that depend on Resrcify.SharedKernel.Results:

Package Downloads
Resrcify.SharedKernel.Web

ASP.NET Core helpers around the result pattern: problem details for failures and unhandled exceptions, reading responses back as results, health endpoints, an ErrorType-keyed HTTP resilience preset and the shared JWT bearer setup.

Resrcify.SharedKernel.Messaging

Implements custom messaging abstractions with support for request/notification dispatching and pipeline behaviors.

Resrcify.SharedKernel.Repository

Implements a generic repository pattern using EntityFrameworkCore.

Resrcify.SharedKernel.Abstractions

Shared cross-cutting abstractions used by multiple SharedKernel projects.

Resrcify.SharedKernel.ArchitectureTesting

Reusable abstract architecture-test base classes built on NetArchTest. Each consumer subclasses the conventional test bases; xUnit picks up the inherited [SkippableFact] / [SkippableTheory] methods. Naming-convention auto-discovery resolves layer assemblies from the consumer's test assembly.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.4.0 44 10/16/2026
4.3.0 71 10/16/2026
4.2.0 142 10/14/2026
4.1.0 122 10/14/2026
4.0.0 249 10/13/2026
3.0.0 244 10/3/2026
2.2.0 249 9/13/2026
2.1.1 1,567 6/8/2026
2.1.0 210 5/24/2026
2.0.0 214 5/22/2026
1.16.3 336 5/7/2026
1.16.2 206 5/7/2026
1.16.1 201 5/7/2026
1.16.0 196 5/7/2026
1.15.0 582 4/18/2026