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
<PackageReference Include="Resrcify.SharedKernel.Results" Version="4.4.0" />
<PackageVersion Include="Resrcify.SharedKernel.Results" Version="4.4.0" />
<PackageReference Include="Resrcify.SharedKernel.Results" />
paket add Resrcify.SharedKernel.Results --version 4.4.0
#r "nuget: Resrcify.SharedKernel.Results, 4.4.0"
#:package Resrcify.SharedKernel.Results@4.4.0
#addin nuget:?package=Resrcify.SharedKernel.Results&version=4.4.0
#tool nuget:?package=Resrcify.SharedKernel.Results&version=4.4.0
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/:ResultResult<TValue>ErrorErrorType, withIsTransient():Failure,ExternalFailure,TimeoutandRateLimitmay pass next time;NotFound,Validation,Conflict,Unauthorized,ForbiddenandUnprocessable(well formed, but it breaks a rule of the operation: HTTP 422) are about the request (another try fails the same way).ErrorTypeJsonConverterreads a type this version doesn't know asFailure, 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 matchesError.Codewithout 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 atErroronce across the packages that see it.Diagnostics/TransientFailureExceptionandDiagnostics/TransientFailures: SharedKernel's one rule for whether an exception is transient (IsTransient(exception)), andresult.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
.Valuethrows, checkIsSuccessfirst. - 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 | 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 (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 |