Zentient Results Api Reference Overview - ulfbou/Zentient.Results GitHub Wiki

📚 Overview


Introduction

Zentient.Results is a powerful .NET 9.0 library designed to improve how you handle operation outcomes and errors. It moves away from traditional exception-based control flow, introducing a Result type that clearly communicates whether an operation succeeded with a value or failed with structured error information.

Why Zentient.Results?

This library helps you write more predictable and maintainable code. Instead of relying on exceptions for routine error conditions, Zentient.Results empowers you to:

  • Model Outcomes Clearly: A method returning IResult<T> explicitly signals that it might produce a T or a failure.
  • Encourage Handling: Developers are prompted to explicitly handle both success and failure paths, leading to more resilient applications.
  • Propagate Errors Effectively: Failures, encapsulated in rich ErrorInfo objects, can be effortlessly passed through your application layers, carrying detailed context.

Key Concepts & Principles

Zentient.Results is built on foundational architectural principles:

  • Immutability: All Result and Result<T> instances are immutable once created.
  • Composability (Functional Composition): Use extension methods like Map, Bind, and Then for fluent chaining of operations.
  • Predictable Error Modeling: Failures are structured ErrorInfo objects, providing rich context.
  • Status-Driven Outcomes: Integrates IResultStatus to represent operation status, often mirroring HTTP status codes.
  • Separation of Concerns: Decouples business logic from error reporting and recovery.

Getting Started

Installation

To add Zentient.Results to your project, simply use the .NET CLI:

dotnet add package Zentient.Results

Basic Usage Example

Let's look at a simple scenario: validating an email address.

using Zentient.Results;

public class EmailService
{
    public IResult<bool> IsEmailValid(string email)
    {
        if (string.IsNullOrWhiteSpace(email))
        {
            return Result.Validation<bool>(new ErrorInfo[]
            {
                new ErrorInfo(ErrorCategory.Validation, "EmailEmpty", "Email address cannot be empty.")
            });
        }

        if (!email.Contains("@") || !email.Contains("."))
        {
            return Result.Validation<bool>(new ErrorInfo[]
            {
                new ErrorInfo(ErrorCategory.Validation, "InvalidFormat", "Email address format is invalid.")
            });
        }

        return Result.Success(true, "Email address is valid.");
    }
}

// How to use it:
public class Program
{
    public static void Main(string[] args)
    {
        var service = new EmailService();

        // Valid email
        IResult<bool> validEmailResult = service.IsEmailValid("[email protected]");
        validEmailResult.OnSuccess(isValid => Console.WriteLine($"Valid Email: {isValid} - {validEmailResult.Messages.FirstOrDefault()}"));
        validEmailResult.OnFailure(errors => Console.WriteLine($"Error: {errors.First().Message}"));

        Console.WriteLine("---");

        // Invalid email (empty)
        IResult<bool> emptyEmailResult = service.IsEmailValid("");
        emptyEmailResult.OnSuccess(isValid => Console.WriteLine($"Valid Email: {isValid}"));
        emptyEmailResult.OnFailure(errors => Console.WriteLine($"Error: {errors.First().Message}"));

        Console.WriteLine("---");

        // Invalid email (bad format)
        IResult<bool> malformedEmailResult = service.IsEmailValid("invalid-email");
        malformedEmailResult.OnSuccess(isValid => Console.WriteLine($"Valid Email: {isValid}"));
        malformedEmailResult.OnFailure(errors => Console.WriteLine($"Error: {errors.First().Message}"));
    }
}
⚠️ **GitHub.com Fallback** ⚠️