Skip to content

andrej-dyck/dotnet-extensions-require

Repository files navigation

Require Expressions for .Net

build codecov NuGet

A small library that provides pre-condition checks as an extension method on types. This allows the client code to check a condition on arguments and use the value directly if no exception is thrown.

Reservation Request(DateTime now, DateTime reservationDate, int seats) => 
    new Reservation(
        reservationDate.Require(d => d > now, d => $"Reservation date {d} must be in the future"),
        seats.Require(seats > 0, () => "Expected positive number of seats")
    );

NuGet Package

dotnet add package Require-Expressions

Examples for Require

Basic Require function

var requestedSeats = seats.Require(condition: seats > 0);
// throws ArgumentException with "expected: seats > 0" as message when condition is not met

var requestedSeats = seats.Require(
    condition: seats > 0,
    expectation: "Expected positive number of seats" // or with custom expectation message
);

Require functions with lazily constructed expectation messages

var requestedSeats = seats.Require(
    condition: seats > 0,
    expectation: () => "Expected positive number of seats"
);

var requestedDate = reservationDate.Require(
    condition: reservationDate > now,
    expectation: d => $"Reservation date {d} must be in the future"
);

Require functions with predicate for convenience

var requestedSeats = seats.Require(condition: s => s > 0);
// throws ArgumentException with "expected: s => s > 0" as message when condition is not met

var requestedSeats = seats.Require(
    condition: s => s > 0,
    expectation: "Expected positive number of seats" // or with custom expectation message
);

var requestedDate = reservationDate.Require(
    requirement: d => d > now,
    expectation: d => $"Reservation date {d} must be in the future"
);

Examples for Check

For checks other than on arguments, the Check function can be used

var reservationRequest = JsonSerializer.Deserialize<Reservation>(request)
    .Check(requirement: r => r.Seats > 0) // expectation message will be "expected r => r.Seats > 0"
    .Check(r => r.Date > now, r => $"Reservation date {r.Date} must be in the future")
    // throws CheckFailed with expectation as message when requirement is not satisfied

With Check, custom exceptions can be constructed

var reservationRequest = JsonSerializer.Deserialize<Reservation>(request)
    .Check(r => r.Seats > 0, exception: () => new SeatsMustBePositive())
    .Check(r => r.Date > now, exception: r => new MustBeFutureDateReservateion(r.Date))

Q&A

Why yet another preconditions library?

Most libraries I found use precondition statements, while I found preconditions as expressions more useful. For example, the latter allows for expression-bodied functions.

I don't like extension methods

No problem, there are many other great precondition libraries. Have a look at .Net's contracts.

I don't want yet another dependency

No problem, just copy&paste the code you need into your project. Or use the build-in .Net contracts.

Can you add this function too?

Probably not as I want to keep this library small and focused. But you are very welcome to post a PR.

Build & Test

Build project

dotnet build 

Run unit tests

dotnet test