Ghanavats.ResultPattern 1.1.2

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

Ghanavats Result Pattern package

Consistent and Flexible Result Handling for Developers to have better control over responses.

Overview

The Ghanavats.ResultPattern NuGet package offers a powerful and adaptable approach to returning results from methods and handlers.

Built on a well-known pattern, this implementation provides flexibility for developers to design and extend their own result-handling strategies.

Key features

  • Generic Results: Support for results based on any type, ensuring versatility across various use cases.
  • Non-Generic Convenience**: Use Result.Success(), Result.Error("..."), or Result.Invalid(...) without specifying a type when no return value is needed.
  • Built-in Statuses (for now!):
    • Ok – Operation succeeded with a value.
    • Error – Operation failed with one or more error messages.
    • Invalid – Validation failed, optionally with detailed ValidationError objects.
    • NotFound – Target entity was not found.
  • Rich Error Handling: Supports both simple error messages and structured validation details.
  • Implicit Conversions: Provides convenient operators for automatic conversion between Result<T> and common return patterns.
  • Validation Support: Integrated with FluentAssertion's ValidationResult, it includes an extension method - PopulateValidationErrors - to populate a list of ValidationError instances. The custom ValidationError class simplifies returning invalid results with validation failures clearly defined.
  • Aggregating multiple results into a single object.

How does it work?

Ghanavats Result Pattern supports both generic and non-generic scenarios. If it's more convenient, use it without specifying a type, otherwise use the generic variant.

General Usage Example

Let's say you have a method to create a User via a repository. You want to use Result Pattern for flow control.

public Result<User> CreateUser(CreateUserRequest request)
{
    if (string.IsNullOrWhiteSpace(request.Email))
    {
        return Result<User>.Invalid(new[]
        {
            new ValidationError("Email is required.", "Email")
        });
    }

    if (_userRepository.Exists(request.Email))
    {
        return Result<User>.Error("User already exists.");
    }

    var user = new User(request.Email);
    _userRepository.Add(user);

    return Result<User>.Success(user, "User created successfully.");
}

Now, let's say the caller consumes CreateUser and needs to check the result.

var result = userService.CreateUser(request);

if(result.IsSuccess)
{
    // take care of the logic here
}

if(result.Status == ResultStatus.Error)
{
    // Do what you need to do
}

Aggregate

The Aggregate method provides a simple and consistent way to group multiple Result instances (such as from multiple internal service calls or business rule validations) into a summarised collection of outcomes by status (e.g. Error, Invalid).

It’s ideal when you:

  • Need to collate results from multiple operations
  • Want to detect overall failure status (e.g. if any error occurred)
  • Need to collect all error messages in a structured way
  • Prefer a clean format to return or log aggregated outcomes
Usage Example
var results = new[]
{
    Result.Ok(),
    Result.Error("Database connection failed."),
    Result.Invalid([new ValidationError("Email is required.")])
};

var aggregated = Result.Aggregate(results);

Output (simplified):

[
  {
    "Status": "Error",
    "Messages": ["Database connection failed."],
    "ValidationErrors": null
  },
  {
    "Status": "Invalid",
    "Messages": ["Email is required."],
    "ValidationErrors": null
  }
]

Optional: Include Structured Validation Errors

By default, Invalid results will only expose error messages as strings. If you need structured validation detail (ValidationError objects), use:

var aggregated = Result.Aggregate(results)
                       .WithFullValidationErrors();

Output

[
  {
    "Status": "Invalid",
    "Messages": [],
    "ValidationErrors": [
      { "ErrorMessage": "Email is required.", "ErrorCode": "Email", "ValidationErrorType": "Error" }
    ]
  }
]

When WithFullValidationErrors() is used, Messages for Invalid entries will be cleared to avoid duplication or inconsistency.

Key Behaviours
  • ResultStatus.Ok and NotFound are excluded from the aggregation by default.
  • Aggregated results are grouped by ResultStatus.
  • Only Messages or ValidationErrors are populated — never both for a single result.
  • Safe to use in the response DTOs, API logging, or composite operations.
Product Compatible and additional computed target framework versions.
.NET 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.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.2 70 8/3/2025
1.1.1 99 7/27/2025
1.1.0 215 7/19/2025
1.0.2 79 5/3/2025
1.0.0 106 1/5/2025