Swallow.Validation 0.5.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package Swallow.Validation --version 0.5.3
NuGet\Install-Package Swallow.Validation -Version 0.5.3
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="Swallow.Validation" Version="0.5.3" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Swallow.Validation --version 0.5.3
#r "nuget: Swallow.Validation, 0.5.3"
#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.
// Install Swallow.Validation as a Cake Addin
#addin nuget:?package=Swallow.Validation&version=0.5.3

// Install Swallow.Validation as a Cake Tool
#tool nuget:?package=Swallow.Validation&version=0.5.3

Swallow.Validation

A lightweight, fluent-style validation library for C#. But what does that mean? That means minimal dependencies (none, actually) and great programmer experience. If you've seen Fluent Assertions, you might find some similarities.

Getting started

Validating values

A validation is created using Validator.Check(). To then actually validate a value, call That() on the validator followed by Satisfies():

Validator.Check()
    .That(() => myValue).Satisfies(x => x > 1, "be larger than 1")

You can chain another validation rule directly after the Satisfies the same as before:

Validator.Check()
    .That(() => myValue).Satisfies(x => x > 1, "be larger than 1")
    .That(() => myName).Satisfies(s => s != null, "not be null")

See that nice string? It determines what the validation error will say if the predicate is not met - if myName is null, a validation error saying "myName must not be null" will be produced. The name of the value is automatically determined, but you can of course pass it yourself, too!

Validator.Check()
    .That(() => myValue, "ThatValue").Satisfies(x => x > 1, "be larger than 1")
    .That(() => myName, "ThatName").Satisfies(s => s != null, "not be null")

To actually retrieve the validation errors - or a positive result - you can use Then().

var result = Validator.Check()
    .That(() => myValue, "ThatValue").Satisfies(x => x > 1, "be larger than 1")
    .That(() => myName, "ThatName").Satisfies(s => s != null, "not be null")
    .Then(() => new MyFancyClass(myValue, myName));

The function is executed only when there are no validation errors. What you get is a ValidationResult<MyFancyClass> where you can check the status with IsSuccess, get a list of all errors with Errors or the created value with Value.

If you don't need a result and only want to handle errors, you can similarily use Else():

Validator.Check()
    .That(() => myValue, "ThatValue").Satisfies(x => x > 1, "be larger than 1")
    .That(() => myName, "ThatName").Satisfies(s => s != null, "not be null")
    .Else(errs => throw new Exception($"{errs.Count} validation errors happened!"));

Conditional validation

If you have a validation rule that should only be checked on certain conditions, you can add a When()-call after the Satisfies() to specify when to validate and when to skip.

Validator.Check()
    .That(() => myName).Satisfies(s => s != null, "not be null")
    .That(() => myName).Satisfies(s => s.Length > 1, "not be empty").When(() => myName != null)

This way, s.Length > 1 is only executed iff myName is not null - no NullReferenceException here.

Custom validation errors

Passing a string to Satisfies() is a simple way to control the resulting validation error, but why stop there?

class IsNullError : ValidationError
{
    public override string ToString() => $"{PropertyName} is null when it's not supposed to!";
}

...

Validator.Check()
    .That(() => myName).Satisfies(s => s != null, _ => new IsNullError())

Named assertions

Using Satisfies() over and over again and specifying the very same predicate and error all over the place is not very DRY, so you can instead provide extension methods to give these assertions memorable names:

public static class MyAssertions
{
    public static IConditionable<IsNullError> IsNotNull<T>(this IAssertable<T> property)
    {
        return property.Satisfies(x => x != null, _ => new IsNullError());
    }
}

...

Validator.Check()
    .That(() => myName).IsNotNull()

Single-call assertions

If you do not like having to call two or three methods for a single validation, you can instead put everything into a combined That()-call:

Validator.Check()
    .That(() => myName, a => a.IsNotNull(a))
    .That(() => myValue, x => x > 1, () => myName != null)

This will simply expand to:

Validator.Check()
    .That(() => myName).IsNotNull()
    .That(() => myValue).Satisfies(x => x > 1, "satisfy predicate").When() => myName != null)

Going deeper

If you wish to know more about the validations and what you can do with them, I suggest you just find out by digging through the code or just using the library to build some validations.

And if you feel like something is missing (or just plain broken), feel free to create an issue.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  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 was computed.  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 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Swallow.Validation:

Package Downloads
Swallow.Validation.ServiceCollection

A lightweight, fluent-style validation library

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
7.0.0 1,008 1/20/2024
6.0.1 1,059 7/2/2023
6.0.0 2,085 1/22/2023
5.0.1 709 11/13/2022
4.2.0 828 6/20/2022
4.1.1 576 5/29/2022
4.1.0 752 2/13/2022
4.0.0 511 2/13/2022
3.1.0 22,319 6/5/2021
3.0.0 448 5/20/2021
2.0.0 436 3/6/2021
1.5.0 2,211 11/23/2020
1.4.0 410 9/4/2020
1.3.0 575 7/20/2020
1.2.0 1,352 6/4/2020
1.1.1 456 5/9/2020
1.1.0 437 5/5/2020
1.0.0 550 4/29/2020
0.12.3 478 4/5/2020
0.12.2 440 4/3/2020
0.12.1 11,241 3/16/2020
0.12.0 471 3/14/2020
0.11.2 569 2/29/2020
0.11.1 523 2/16/2020
0.11.0 503 2/13/2020
0.10.3 496 2/12/2020
0.10.2 541 1/31/2020
0.10.1 508 1/27/2020
0.10.0 505 1/5/2020
0.9.1 460 1/3/2020
0.8.0 448 12/21/2019
0.7.3 4,913 11/27/2019
0.7.2 464 11/9/2019
0.7.1 449 11/9/2019
0.7.0 467 11/9/2019
0.6.1 458 10/27/2019
0.5.3 462 10/23/2019
0.5.2 446 10/21/2019
0.5.1 450 10/20/2019
0.4.2 479 9/14/2019
0.4.1 482 9/7/2019
0.3.3 479 9/7/2019
0.3.2 528 8/28/2019
0.3.1 499 8/24/2019
0.2.4 478 8/24/2019
0.2.3 540 8/24/2019