Zentient.Results 0.4.4

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

Zentient.Results

NuGet Build License .NET Versions

Zentient.Results is a lightweight, opinionated .NET library that provides a robust and consistent approach to handling operation outcomes. It introduces immutable result types to encapsulate success values or structured error information, promoting clean architecture principles, enhancing code readability, and streamlining error propagation across application layers. This framework is designed to align with modern functional programming paradigms and improve the predictability of your application's behavior.


ℹ️ v0.4.1 Update:
Minor changes in v0.4.1 mitigate the breaking changes introduced in v0.4.0 by expanding internal visibility to the Zentient.Endpoints, Zentient.Telemetry, and related libraries. This ensures smoother integration and compatibility for consumers of these packages, especially when using advanced scenarios or extension libraries within the Zentient ecosystem.


Key Features

  • Immutable Result Types: Result (for void operations) and Result<T> (for operations returning a value) ensure that outcomes are fixed once created, promoting predictable data flow.
  • Structured Error Information: Failures are represented by ErrorInfo objects, providing categorized codes, human-readable messages, and optional contextual data or inner errors.
  • Fluent API for Composition: Enables chaining and transforming results using methods like Map, Bind, OnSuccess, and OnFailure, facilitating clean, composable business logic.
  • Clear Status Separation: Distinguishes between the operation's outcome (IsSuccess/IsFailure) and its detailed status (IResultStatus), which can align with HTTP status codes or custom domain-specific states.
  • Extensible Status System: The IResultStatus interface allows for the definition of custom result statuses beyond standard HTTP responses, providing flexibility for domain-specific outcomes.
  • Built-in HTTP Status Alignment: Predefined ResultStatus constants (e.g., ResultStatuses.Success, ResultStatuses.BadRequest, ResultStatuses.NotFound) simplify mapping results to standard HTTP responses.
  • Lightweight and Minimal Dependencies: Designed with minimal external dependencies to ensure a small footprint and easy integration into any .NET project.

Installation

Install Zentient.Results via NuGet Package Manager:

dotnet add package Zentient.Results

Zentient.Results targets .NET 6+, .NET 7+, .NET 8+, and .NET 9.

Getting Started

Here's a quick example demonstrating basic usage:

using System;
using System.Collections.Generic;

using Zentient.Results;

public class UserService
{
    // Example: Operation that can succeed or fail
    public IResult<User> GetUserById(Guid id)
    {
	if (id == Guid.Empty)
	{
	    return Result<User>.Failure(
		default,
		new ErrorInfo(ErrorCategory.Validation, "InvalidId", "User ID cannot be empty."),
		ResultStatuses.BadRequest);
	}
	
	// Simulate fetching a user
	if (id == new Guid("A0000000-0000-0000-0000-000000000001"))
	{
	    return Result<User>.Success(new User { Id = id, Name = "Alice" });
	}
	
	return Result<User>.Failure(
	    default,
	    new ErrorInfo(ErrorCategory.NotFound, "UserNotFound", $"User with ID {id} was not found."),
	    ResultStatuses.NotFound);
    }

    // Example: Chaining operations
    public IResult<string> GetUserName(Guid userId)
    {
	return GetUserById(userId)
	    .Map(user => user.Name) // Extract user name if successful
	    .OnFailure(errors => Console.WriteLine($"Failed to get user name: {errors[0].Message}")); // Log error
    }
}
public class User
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
	var userService = new UserService();
    // Successful call
	var successResult = userService.GetUserById(new Guid("A0000000-0000-0000-0000-000000000001"));
	if (successResult.IsSuccess)
	{
	    Console.WriteLine($"User found: {successResult.Value.Name}");
	}

	// Failed call - User not found
	var notFoundResult = userService.GetUserById(Guid.NewGuid());
	if (notFoundResult.IsFailure)
	{
	    Console.WriteLine($"Error: {notFoundResult.Error}");
	    Console.WriteLine($"Status Code: {notFoundResult.Status.Code}, Description: {notFoundResult.Status.Description}");
	}

	// Chained operation
	var chainedSuccess = userService.GetUserName(new Guid("A0000000-0000-0000-0000-000000000001"));
	if (chainedSuccess.IsSuccess)
	{
	    Console.WriteLine($"Chained user name: {chainedSuccess.Value}");
	}

	var chainedFailure = userService.GetUserName(Guid.Empty); // Will trigger validation error
	// OnFailure action in GetUserName will be executed here
    }
}

Usage Scenarios

Zentient.Results is particularly effective in scenarios requiring robust error handling and clear communication of operational outcomes:

  • Application Service Layers: Return IResult or IResult<T> from business logic methods to clearly indicate success or specific failure conditions, separating concerns from presentation.
  • Controller Result Handling: Directly map IResult instances from service calls to appropriate ASP.NET Core IActionResult types (e.g., Ok, BadRequest, NotFound, UnprocessableEntity).
  • Background Jobs or Middleware: Standardize the reporting of execution outcomes, including detailed error diagnostics for logging and monitoring.
  • Command and Query Handlers (CQRS): Provide explicit results from command execution and query processing, facilitating predictable state changes and data retrieval.
  • Integration with CI/CD Pipelines: Use the structured error information to drive automated validation and error reporting in build and deployment processes.

Architecture & Design Philosophy

Zentient.Results is built on several core design principles:

  • Composition over Inheritance: The framework favors composing Result objects with specific status and error information rather than relying on complex inheritance hierarchies for different outcome types.
  • Encapsulation of Status Logic: IResultStatus and ErrorInfo provide a dedicated, extensible mechanism for describing the outcome, keeping the core Result types focused on flow control.
  • Separation from Exception-Based Flow: While compatible with exceptions (e.g., Result.FromException), the primary goal is to shift from using exceptions for expected control flow to explicit result passing. Exceptions are reserved for truly exceptional and unrecoverable scenarios.
  • Immutability and Predictability: All core result types are readonly structs, ensuring that once an outcome is determined, it cannot be inadvertently modified, leading to more predictable code behavior and easier debugging.

Advanced Topics

  • Custom IResultStatus Implementations: Extend ResultStatus or implement IResultStatus to define domain-specific success or failure states that are not directly mapped to HTTP.
  • ASP.NET Core Integration: Leverage extension methods or middleware to automatically convert IResult types returned from controllers into appropriate IActionResult responses.
  • Serialization Behavior: Result and Result<T> are designed to be compatible with System.Text.Json for seamless serialization, typically exposing IsSuccess, Errors, Messages, and Status properties.

For more in-depth examples and advanced usage patterns, please refer to the Zentient.Results Wiki.

Contributing

We welcome contributions to Zentient.Results! Please refer to our CONTRIBUTING.md for guidelines on how to submit issues, propose features, or contribute code. We adhere to standard .NET coding conventions.

License

Zentient.Results is licensed under the MIT License.

Support & Contact

For any issues, questions, or feature requests, please use the GitHub Issues page.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Zentient.Results:

Package Downloads
Zentient.Endpoints

Core abstractions and utilities for unifying result handling across transport protocols (HTTP, gRPC, Messaging) using Zentient.Results.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.4 232 7/1/2025
0.4.4-beta0001 92 6/29/2025
0.4.2 135 6/27/2025
0.4.1 157 6/23/2025
0.4.0 115 6/21/2025
0.3.0 152 6/7/2025
0.2.0 151 5/28/2025
0.1.0 154 5/22/2025