PraetoR.FluentValidation 1.0.0-alpha

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

PraetoR.FluentValidation 🛡️✨

License: MIT

The official extension to integrate FluentValidation into your PraetoR command and event pipeline. Ensure your commands and queries are always validated before being processed by their respective handlers.

Overview

PraetoR.FluentValidation provides IPipelineBehavior implementations that intercept ICommand and ICommand<TResponse> dispatched through IPraetoR. It automatically locates and executes all registered FluentValidation validators (AbstractValidator<TCommand>) for the given command. If any validation rule fails, a FluentValidation.ValidationException is thrown, preventing the command from reaching its handler.

This library is essential for implementing robust and decoupled validation within your PraetoR-based architecture.

Installation

The easiest way to add PraetoR.FluentValidation to your project is via the NuGet Package Manager.

dotnet add package PraetoR.FluentValidation

You will also need to have PraetoR and FluentValidation.DependencyInjectionExtensions installed in your application project:

dotnet add package PraetoR
dotnet add package FluentValidation.DependencyInjectionExtensions

Configuration

Configure PraetoR.FluentValidation in your Program.cs (or Startup.cs for .NET Framework) alongside the registration of PraetoR and your validators.

using System.Reflection;
using FluentValidation;
using PraetoR.Extensions; // For AddPraetoR
using PraetoR.FluentValidation; // For AddPraetoRFluentValidation

var builder = WebApplication.CreateBuilder(args);

// ... other services

// 1. Register PraetoR and all its handlers within the current assembly
builder.Services.AddPraetoR(Assembly.GetExecutingAssembly());

// 2. Add the Validation Pipeline Behavior to PraetoR
//    This ensures all commands will go through validation
builder.Services.AddPraetoRFluentValidation(Assembly.GetExecutingAssembly());

// ... rest of your application setup and build

Example Usage

1. Define Your Commands and Validators

Create your commands (with or without a return value) and their respective validators inheriting from AbstractValidator<TCommand>.

// Command with a return value
public class CreateUserCommand : ICommand<Guid>
{
    public string UserName { get; }
    public string Email { get; }
    public CreateUserCommand(string userName, string email) { UserName = userName; Email = email; }
}

// Validator for CreateUserCommand
public class CreateUserCommandValidator : AbstractValidator<CreateUserCommand>
{
    public CreateUserCommandValidator()
    {
        RuleFor(x => x.UserName)
            .NotEmpty().WithMessage("User name is required.")
            .MinimumLength(3).WithMessage("User name must be at least 3 characters long.");

        RuleFor(x => x.Email)
            .NotEmpty().WithMessage("Email is required.")
            .EmailAddress().WithMessage("Invalid email format.");
    }
}

// Command without a return value
public class DeleteUserCommand : ICommand
{
    public Guid UserId { get; }
    public DeleteUserCommand(Guid userId) => UserId = userId;
}

// Validator for DeleteUserCommand
public class DeleteUserCommandValidator : AbstractValidator<DeleteUserCommand>
{
    public DeleteUserCommandValidator()
    {
        RuleFor(x => x.UserId).NotEmpty().WithMessage("User ID cannot be empty.");
    }
}

2. Dispatch Your Commands via IPraetoR

In your application logic (e.g., in an API Controller), inject IPraetoR and dispatch your commands. Validation will be executed automatically.

using Microsoft.AspNetCore.Mvc;
using PraetoR.Abstractions;
using FluentValidation; // To catch ValidationException
using System.Linq; // For Select extension method

[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
    private readonly IPraetoR _PraetoR;

    public UsersController(IPraetoR PraetoR)
    {
        _PraetoR = PraetoR;
    }

    [HttpPost]
    public async Task<IActionResult> CreateUser([FromBody] CreateUserRequest request)
    {
        var command = new CreateUserCommand(request.UserName, request.Email);
        try
        {
            var newUserId = await _PraetoR.Send(command); // Validation occurs here!
            return Ok(new { Id = newUserId });
        }
        catch (ValidationException ex)
        {
            // Catch validation failures and return a Bad Request
            return BadRequest(ex.Errors.Select(e => new { Field = e.PropertyName, Message = e.ErrorMessage }));
        }
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteUser(Guid id)
    {
        var command = new DeleteUserCommand(id);
        try
        {
            await _PraetoR.Send(command); // Validation occurs here!
            return NoContent();
        }
        catch (ValidationException ex)
        {
            return BadRequest(ex.Errors.Select(e => new { Field = e.PropertyName, Message = e.ErrorMessage }));
        }
    }
}

How It Works (Internally)

PraetoR.FluentValidation registers two distinct IPipelineBehavior implementations:

  • ValidationBehavior<TRequest, TResponse>: Used for commands that implement ICommand<TResponse>.
  • ValidationBehaviorNoResult<TRequest>: Used for commands that implement only ICommand.

Both behaviors intercept the command, resolve all IValidator<TRequest> for that specific command from the DI container, and execute them. If any failures are found, a ValidationException is thrown, halting the pipeline's execution.

Contributing

Contributions are welcome! If you find a bug or have a suggestion for an improvement, feel free to open an issue or submit a Pull Request.

License

This project is licensed under the MIT License. See the LICENSE file for more details.

Product Compatible and additional computed target framework versions.
.NET 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.0.0-alpha 54 9/27/2025