PredicationBuilder composes a Boolean rule from predicate types. Start the rule with Create<T>() or Not<T>(), add combinations, and call Build() to obtain an executable predicate.

Start a rule

var builder = new PredicationBuilder()
    .Create<StartsWith>("Nik");

var predicate = builder.Build();
Assert.That(predicate.Evaluate("Nikola Tesla"), Is.True);

Use Not<T>() instead of Create<T>() when the first predicate must be negated.

Combine predicates

Append predicates with And<T>(), Or<T>(), and Xor<T>():

var builder = new PredicationBuilder()
    .Create<StartsWith>("ola")
    .Or<EndsWith>("sla")
    .And<SortedAfter>("Alan Turing")
    .Xor<SortedBefore>("Marie Curie");

var predicate = builder.Build();
Assert.That(predicate.Evaluate("Nikola Tesla"), Is.True);

The fluent call order defines the combination order. For mixed operators, extract a grouped subrule so the intended logic remains visible.

Negate a combined predicate

Use AndNot<T>(), OrNot<T>(), or XorNot<T>():

var builder = new PredicationBuilder()
    .Create<StartsWith>("ola")
    .OrNot<EndsWith>("Tes");

var predicate = builder.Build();
Assert.That(predicate.Evaluate("Nikola Tesla"), Is.True);

Group a subrule

Build a subrule and pass it to And(...), Or(...), or Xor(...). The subrule becomes a group:

var name = new PredicationBuilder()
    .Create<StartsWith>("Nik")
    .And<EndsWith>("sla");

var builder = new PredicationBuilder()
    .Create<LowerCase>()
    .Or(name)
    .Or<UpperCase>();

var source = builder.Serialize();
Assert.That(source, Is.EqualTo(
    "{{lower-case |OR {starts-with(Nik) |AND ends-with(sla)}} |OR upper-case}"
));
flowchart LR
    A[starts-with] --> C[AND group]
    B[ends-with] --> C
    C --> D[OR]
    E[lower-case] --> D

Read parameters from a context

As with ExpressionBuilder, parameter expressions can read variables and the current object from an IContext:

var context = new Context();
context.Variables.Add<string>("prefix", "Nik");

var builder = new PredicationBuilder(context)
    .Create<StartsWith>(ctx => ctx.Variables["prefix"]);

var predicate = builder.Build();

Context parameter expressions are resolved during evaluation, so a shared context can supply changing values to a reusable predicate.


This site uses Just the Docs, a documentation theme for Jekyll.