Skip to content

Oficial-CleanValidation/CleanValidation.CSharp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

35 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

CleanValidation.Core 🐚

The .NET library for fluent, expressive, and clean validation using the best of multiple patterns: Guard, Result<T>, and extensible validators with localization support built-in.


πŸš€ Getting Started

1. Add the NuGet package:

https://www.nuget.org/packages/CleanValidation.Core

Install-Package CleanValidation.Core

✨ Key Features

  • βœ… Fluent validation syntax using Guard
  • βœ… Built-in Result<T> system: SuccessResult, ErrorResult, InvalidResult, ConflictResult, etc.
  • βœ… Separate Guard and GuardThrow for result-based or exception-based flows
  • βœ… Extensible IValidator<T> interface for custom validations
  • βœ… Localization support via cultureName
  • βœ… Fully composable, testable, and DI-ready

⚑ Quick Example

public record User(long Id, string Name, byte Age, long UserTypeId, string Description);

public class UserValidator(IUserTypeRepository userTypeRepository) : Validator<User>
{
    private readonly IUserTypeRepository _userTypeRepository = userTypeRepository;

    public override async Task<IResult> ValidateAsync(
        User value,
        string cultureName = "en-US",
        CancellationToken cancellationToken = default)
    {
        var result = await base.ValidateAsync(value, cultureName, cancellationToken);

        if (!result.Success)
            return result;

        var exists = await _userTypeRepository.ExistsAsync(value.UserTypeId, cancellationToken);

        if (!exists)
            return NotFoundResult.Create(new Error(message: "Invalid user type id", field: nameof(user.UserTypeId)));

        return Guard.Create()
            .AgainstNullOrWhiteSpace(value.Name)
            .AgainstNullOrWhiteSpace(value.Description)
            .GetResult();
    }
}

πŸ”¨ Core Concepts

Guard

Fluent and chainable validation that returns a Result<T>:

Guard.Create()
    .AgainstNull(dto)
    .AgainstNullOrWhiteSpace(dto.Name)
    .GetResult();

GuardThrow

Same as Guard, but throws exceptions instead:

GuardThrow.Create()
    .AgainstNull(entity)
    .AgainstNullOrWhiteSpace(entity.Name);

Result Types

All results implement IResult or IResult<T>:

  • SuccessResult<T>
  • ErrorResult<T>
  • InvalidResult<T>
  • ConflictResult<T>
  • NotFoundResult<T>
  • ProblemResult<T>

Each provides fluent creation with error details and optional field association.


πŸ” Localization Support

All methods that return or create results accept a cultureName parameter, used internally with .resx resources to localize messages dynamically.

Guard.Create("pt-BR")
    .AgainstNullOrWhiteSpace(dto.Descricao)
    .GetResult();

βš™ Structure Overview

  • Error – Base error model with Message and Field
  • ErrorUtils – Factory methods for consistent error creation
  • CleanValidationException – Base exception with helper ThrowIfNull, ThrowIfNullOrWhiteSpace, etc.
  • Guard – Fluent builder that returns results
  • GuardThrow – Fluent builder that throws exceptions
  • IResult / IResult – Interfaces for all result types
  • Validator / IValidator – Abstract class + interface for async or sync custom validation logic
  • ResultExtensions – Helpful extensions like ErrorsTo<T>()

🌐 Goals & Philosophy

  • Minimalism + Expressiveness
  • Strong typing, fail-fast, and readability
  • Plug-and-play usability
  • Clear separation between structural validation and business rules
  • Encouragement of clean architecture without forcing opinionated structures

βœ… Next Steps

  • Check out CleanValidation.Extensions.Http for ASP.NET Core integration
  • Use CleanValidation.DependencyInjection to register all IValidator<T> via Scrutor

πŸͺ€ Inspiration

This library combines the clarity of Guard clauses, the safety of Result<T>, and the convenience of fluent interfaces β€” all wrapped with localization and extensibility in mind.

CleanValidation: The .NET library for Clean Validations with clarity, consistency, and control. 🐚


CleanValidation.Extensions.Http 🌐

ASP.NET integration for CleanValidation.

This package provides seamless mapping from IResult / IResult<T> (from CleanValidation.Core) into ASP.NET Core IActionResult types, enabling fluent and expressive return statements in your controller or endpoint layer.


✨ Features

  • βœ… Maps SuccessResult<T> to OkObjectResult
  • βœ… Maps ErrorResult<T> to BadRequestObjectResult
  • βœ… Maps InvalidResult<T> to UnprocessableEntityObjectResult
  • βœ… Supports ConflictResult<T>, NotFoundResult<T>, ProblemResult<T>
  • βœ… Simple .ToActionResult() extension method for all IResult
  • βœ… Consistent HTTP responses for clean architecture applications

πŸš€ Getting Started

1. Add the NuGet package:

https://www.nuget.org/packages/CleanValidation.Extensions.Http

Install-Package CleanValidation.Extensions.Http

2. Use in Controller or Minimal API:

using CleanValidation.Extensions.Http;

User user = new("LΓ­via", 21, "Lady");
IResult<User> result = SuccessResult<User>.Create(user);

IActionResult actionResult = result.ToActionResult();

3. Example Mapping:

return result.ToActionResult();

This will automatically return:

  • Ok(user) if result is a SuccessResult<T>
  • BadRequest(...) if result is an ErrorResult<T>
  • UnprocessableEntity(...) if result is an InvalidResult<T>
  • Conflict(...) if result is a ConflictResult<T>
  • NotFound(...) if result is a NotFoundResult<T>
  • Problem(...) if result is a ProblemResult<T>

🎑 Why Use It?

  • Makes controllers and endpoints cleaner and less error-prone
  • Eliminates repetitive response handling logic
  • Promotes consistency across all HTTP layers
  • Fits perfectly into CQRS, Minimal APIs, and RESTful patterns

πŸŽ“ Example Test

User user = new("LΓ­via", 21, "Lady");
IResult<User> result = SuccessResult<User>.Create(user);

IActionResult actionResult = result.ToActionResult();

Assert.NotNull(actionResult);
Assert.IsType<OkObjectResult>(actionResult);

Use CleanValidation.Extensions.Http to make your ASP.NET Core apps fluent, expressive, and consistent from validation to response.


CleanValidation.DependencyInjection βš™οΈ

Plug-and-play integration for CleanValidation with ASP.NET Dependency Injection, using Scrutor under the hood to automatically register validators.


✨ Features

  • βœ… Auto-registers all IValidator<T> implementations as Scoped
  • βœ… Easy-to-use extension method: AddCleanValidation(...)
  • βœ… Supports multiple assemblies or a single reference
  • βœ… No configuration required β€” just plug and go

πŸš€ Getting Started

1. Install the package:

https://www.nuget.org/packages/CleanValidation.DependencyInjection

Install-Package CleanValidation.DependencyInjection

2. Register your validators in Startup.cs or Program.cs:

using CleanValidation.DependencyInjection;

var services = new ServiceCollection();
services.AddCleanValidation(typeof(UserValidator).Assembly);

Or for multiple assemblies:

services.AddCleanValidation(
    typeof(UserValidator).Assembly,
    typeof(OtherValidator).Assembly
);

πŸͺ€ How It Works

This extension method uses Scrutor to scan the specified assemblies and register all types that implement:

IValidator<T>

πŸ” Example

public class UserValidator : Validator<User>
{
    public override Task<IResult> ValidateAsync(User value, string cultureName = "en-US", CancellationToken cancellationToken = default)
    {
        return Task.FromResult(Guard.Create(cultureName)
            .AgainstNullOrWhiteSpace(value.Name)
            .AgainstNullOrWhiteSpace(value.Description)
            .GetResult());
    }
}

Then simply inject it:

public class UserHandler
{
    private readonly IValidator<User> _validator;

    public UserHandler(IValidator<User> validator)
    {
        _validator = validator;
    }

    public async Task<IResult> HandleAsync(User user)
    {
        return await _validator.ValidateAsync(user);
    }
}

CleanValidation.DependencyInjection makes your validators discoverable, injectable, and production-ready β€” instantly.


πŸ› CleanValidation Ecosystem

Package Description
CleanValidation.Core Fluent validation with Guard + Result
CleanValidation.Extensions.Http HTTP mapping of results to IActionResult
CleanValidation.DependencyInjection Registers IValidator<T> via Scrutor

About

The .NET library for Clean Validations. 🐚

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages