Skip to content
deniscuciucPublic

About

Rules, feature flags, segments and A/B tests for .NET from one expression language.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Rulebook

Rulebook

CI NuGet License .NET

Rules, feature flags, segments and A/B tests in .NET — from one expression language.

Write the condition once, as a string:

user.tier == 'gold' && cart.total > 100

Rulebook parses it, compiles it to a delegate, and evaluates it against whatever context you hand it. Feature flags, audience segments and A/B experiments are all the same rule with a different wrapper.

dotnet add package Rulebook
builder.Services.AddDecisions();
builder.Services.AddDecisionDefinitions(builder.Configuration);
{
  "Rulebook": {
    "FeatureFlags": [
      {
        "Id": "new-checkout",
        "Name": "New checkout",
        "Rule": "user.tier == 'gold' && user.country == 'US'",
        "RolloutPercentage": 25
      }
    ]
  }
}
public sealed class CheckoutService(
    IDecisionEngine engine,
    IDecisionDefinitionProvider definitions)
{
    public async Task<bool> UseNewCheckoutAsync(User user, CancellationToken cancellationToken)
    {
        var flags = await definitions.GetFeatureFlagsAsync(cancellationToken);
        var flag = flags.Single(f => f.Id == "new-checkout");

        var context = new DictionaryDecisionContext(new Dictionary<string, object?>
        {
            ["user.tier"] = user.Tier,
            ["user.country"] = user.Country,
            ["subject.id"] = user.Id,
        });

        var result = await engine.EvaluateFeatureFlagAsync(flag, context, cancellationToken);
        return result.IsMatch;
    }
}

Change the rule in configuration and the next evaluation uses it — no restart, no deploy. A rule that does not parse throws on first use and names the definition, rather than quietly evaluating to false.

What you get

Rules A small boolean DSL — == != > < >= <= in not in contains starts_with ends_with, &&, ||, !, parentheses. Parsed to an AST, compiled to a delegate, cached.
Feature flags A rule plus a rollout percentage.
Segments A named rule. Ask which segments a subject falls into.
A/B tests Deterministic bucketing — XxHash32("{experimentId}:{subjectId}"), weighted variants, optional salt. The same subject always lands in the same variant, with no stored state and no coordination between instances.
Custom operators Register your own; the registry is open.

Context

A decision is evaluated against an IDecisionContext, which resolves dotted paths. Nothing about the shape of your data is baked in.

var context = new DictionaryDecisionContext(new Dictionary<string, object?>
{
    ["player.level"] = 25,
    ["player.country"] = "US",
    ["subject.id"] = "user-42",
});

There is a synchronous fast path (TryGetValue) and an async fallback (GetValueAsync) for values that have to be fetched. CompositeDecisionContext layers several sources.

Definitions from anywhere

AddDecisionDefinitions(IConfiguration) reads from configuration through IOptionsMonitor, so any reloadable source gives hot reload. To load from a database or a feature-flag service instead, implement IDecisionDefinitionProvider and register it:

services.AddDecisionDefinitionProvider<MyDefinitionProvider>();

Registration is TryAdd, so yours wins over the built-in one regardless of order.

Packages

Package What you get
Rulebook The engine: parser, compiler, operators, contexts, evaluators, definition sources
Rulebook.Abstractions Contracts and definition models, with no dependencies. Reference this from a project that describes decisions without evaluating them.

Documentation

A runnable example lives in examples/Rulebook.Examples.Console, and there are BenchmarkDotNet suites in tests/Rulebook.Benchmarks.

Versioning

Semantic versioning. Both packages are versioned and released together. Breaking changes are listed in CHANGELOG.md.

Targets net10.0. Building from source needs the .NET 10 SDK.

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md, CODE_OF_CONDUCT.md and SECURITY.md.

License

MIT

About

Rules, feature flags, segments and A/B tests for .NET from one expression language.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages