Skip to content

Constraints

Constraints are the heart of assertions. They describe in detail the expectations placed on entities and values.

Use Cases

Needing a constant constraint result

Sometimes you need to have a constraint constraint result. In such cases you can use Always.True and Always.False.

An example could be checking if an entity exists at least once:

[Assertion]
public Constraint AtLeastOneBlogPostExists()
{
    return Check.For(Times.AtLeastOnce, (Post post) => Always.True);
}

Invert a constraint

It may be easier to forumalte the opposite of what you actually want to assert. In those cases you can use Not to invert the constraint.

constraint.Not()

AND-combine multiple constraints

When multiple constraints have to match then you can use And to combine them.

constraintA.And(constraintB).And(constraintC, constraintD)
Check.And(constraintA, constraintB, constraintC, constraintD)

OR-combine multiple constraints

When only at least one constraint has to match then you can use Or to combine them.

constraintA.Or(constraintB).Or(constraintC, constraintD)
Check.Or(constraintA, constraintB, constraintC, constraintD)

XOR-combine multiple constraints

When only one out of multiple constraints is allowed to match then you can use Xor to combine them.

constraintA.Xor(constraintB).Xor(constraintC, constraintD)
Check.Xor(constraintA, constraintB, constraintC, constraintD)

Only assert X if Y holds

If you only care if a constraint holds, if another constraint also holds, then you can use Implies to express this. When the other constraint does not match the combined constraint is successful. Otherwise it is only successful if both constraints match.

[Assertion]
public Constraint NormalizedNameIsUniqueAcrossOrganization()
{
    return Check.ForAllDisjunct<Runner>((a, b) =>
        a.OrganizationId.IsEqualTo(b.OrganizationId)
        .Implies(a.NormalizedName.IsNotEqualTo(b.NormalizedName)));
}