FluentEnforce 2.1.0

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

FluentEnforce

FluentEnforce

NuGet Downloads License: MIT GitHub

Lightweight, expressive parameter validation for .NET: 100+ built-in validations, fluent API, extensible architecture. Fail fast at method boundaries with zero boilerplate.

Table of contents

Why FluentEnforce

  • Readable validation chains: email.EnforceNotNull().NotWhiteSpace().MatchesEmail()
  • 100+ unique built-in checks: strings, numbers, dates, collections, enums, GUIDs, and more
  • Dual exception modes: standard ArgumentException (and its inherited types) or your custom exceptions
  • Method boundary defense: validate early, fail fast
  • Zero overhead: aggressive inlining (This is removed for now, for more optimization in a later subversion, but the JIT is already smart enough to handle those methods), compiled regex patterns
  • AOT-friendly and fast: AOT compatibility is enabled, optimized equality, no runtime code emission or reflection

Install

dotnet add package FluentEnforce

Targets: net9.0.

Quick tour

Basic validation

// Static approach
Enforce.NotNull(email)
    .NotWhiteSpace()
    .MatchesEmail();

Enforce.That(itemsList)
    .HasMinCount(minItemsToShip)
    .AllMatch(item => item.CanBeShipped);

Enforce.That(endDate).GreaterThan(startDate);

// Extension approach (equivalent)
email.EnforceNotNull()
    .NotWhiteSpace()
    .MatchesEmail();

itemsList.Enforce()
    .HasMinCount(minItemsToShip)
    .AllMatch(item => item.CanBeShipped);

endDate.Enforce().GreaterThan(startDate);

Note: For educational purposes, you will see me switch between using the regular static approach and extension approach. For readability, it's preferable to stick to one approach in a single code block. More about this in the documentation, in the Best Practices section.

Constructor defense

public sealed class Email
{
    public string Value { get; }

    public Email(string value)
    {
        Value = Enforce.NotNull(value)
            .NotWhiteSpace()
            .MatchesEmail()
            .Value; // Get validated value back
            // [Note that `.Value` is optional. The Enforce type already has implicit conversion to the wrapped type]
    }
}

Custom exceptions

email.EnforceNotNull(() => new DomainException("Email required"))
    .MatchesEmail(() => new DomainException("Invalid email format"));

Rich validations

// Numbers
Enforce.That(age).InRange(18, 100, RangeBounds.LeftInclusive);
Enforce.That(price).Positive().LessThan(1000);

// Collections
Enforce.NotNull(items).NotEmpty().HasMinCount(1).HasMaxCount(10);

// Dates
Enforce.That(birthDate).InPast();
Enforce.That(appointment).InFuture();

// Extensible (For repeated validations)
Enforce.That(order1).Valid(); // And we define the extension Valid() method below
Enforce.That(order2).Valid();

static class OrderEnforceExtensions
{
    public static Enforce<Order> Valid(this Enforce<Order> enforce)
    {
        var order = enforce.Value;
        var paramName = enforce.ParamName;

        order.Items.Enforce(paramName).NotEmpty();
        order.Total.EnforceNotNull(paramName).Positive();

        return enforce;
    }

    // Alternative approach.
    // The above method is equavalent to:
    public static Enforce<Order> Valid(this Enforce<Order> enforce)
    {
        var order = enforce.Value;
        var paramName = enforce.ParamName;

        if (!order.Items.Any())
            throw new ArgumentException("Order must have items", paramName);

        if(order.Total <= 0)
            throw new ArgumentOutOfRangeException(paramName, order.Total, "Order total must be positive");

        return enforce;
    }
}

Validation categories

Core types (147 methods)

  • String (41): length, content, patterns, regex patterns, email/URL/phone/IP/GUID formats
  • Numeric (15): comparisons, signs, number types, divisibility
  • Collections (13): count, contained items, uniqueness, predicates (with overloads for the core collection types)
  • DateTime (8 + 5 numeric comparisons): past/future/today checks, numeric comparisons, with TimeProvider support
  • General (5): equality, null, in/not-in sets (With some overloads)
  • TimeSpan (6 + 5 numeric comparisons): signs, numeric comparisons
  • Character (9): letter/digit/whitespace/symbol/special
  • Boolean (2): true/false
  • GUID (2): empty/not-empty
  • Enum (1): defined values

Each validation has both ArgumentException and custom exception variants (in addition to overloads for the collection types).

Documentation

This README stays intentionally brief. Full documentation lives in the docs:

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.
  • net9.0

    • No dependencies.

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
2.1.0 41 8/15/2025