EvalApp.Consumer
1.0.17
dotnet add package EvalApp.Consumer --version 1.0.17
NuGet\Install-Package EvalApp.Consumer -Version 1.0.17
<PackageReference Include="EvalApp.Consumer" Version="1.0.17" />
<PackageVersion Include="EvalApp.Consumer" Version="1.0.17" />
<PackageReference Include="EvalApp.Consumer" />
paket add EvalApp.Consumer --version 1.0.17
#r "nuget: EvalApp.Consumer, 1.0.17"
#:package EvalApp.Consumer@1.0.17
#addin nuget:?package=EvalApp.Consumer&version=1.0.17
#tool nuget:?package=EvalApp.Consumer&version=1.0.17
EvalApp.Consumer
A self-tuning async pipeline engine for .NET 8. Zero dependencies, in-process, single self-contained assembly.
You describe a task as a chain of small steps over an immutable state record. EvalApp compiles that chain once into a pre-built delegate pipeline (no per-call reflection or DI lookups) and runs it. When you supply a license key it also parallelises independent work and tunes its own concurrency at runtime.
60-second quickstart
using EvalApp.Consumer;
// 1. Immutable state — a plain record. Each step returns a new value with `with`.
record OrderData(string Sku, int Quantity, bool IsValidated = false, decimal Total = 0);
// 2. Build the pipeline once at startup. `Run(out ...)` hands you the compiled pipeline;
// `Build(...)` finalises it. Pass a license key to unlock the parallel/tuning engine,
// or omit it to run every step correctly but sequentially (free tier).
ICompiledPipeline<OrderData> pipeline;
EvalApp.App("Orders") // or Eval.App("Orders")
.WithResource(ResourceKind.Network)
.WithTuning() // self-tuning concurrency (needs a license to take effect)
.DefineDomain("OrderProcessing")
.DefineTask<OrderData>("ProcessOrder")
.AddStep("Validate", d => d with { IsValidated = d.Quantity > 0 })
.Gate(ResourceKind.Network, null, g => g
.AddStep("FetchPrice", async (d, ct) =>
d with { Total = await catalog.GetPrice(d.Sku, ct) * d.Quantity }))
.Run(out pipeline)
.Build(licenseKey); // omit licenseKey for the free sequential tier
// 3. Execute. The compiled pipeline is thread-safe — build once, reuse across requests.
PipelineResult<OrderData> result = await pipeline.RunAsync(new OrderData("SKU-001", Quantity: 2), ct);
switch (result)
{
case PipelineResult<OrderData>.Success s:
Console.WriteLine($"Total: {s.Data.Total:C}");
break;
case PipelineResult<OrderData>.Failure f:
Console.Error.WriteLine($"Failed: {f.Exception.Message}");
break;
case PipelineResult<OrderData>.Skipped sk:
Console.WriteLine($"Skipped: {sk.Reason}");
break;
}
Every step returns a PipelineResult<T> — Success, Failure, or Skipped. Use result.GetData() to pull the state out regardless of outcome.
What it does
- Records as state — pipeline state is an immutable record; each step is a pure
d => d with { ... }transform or anasync (d, ct) => .... No shared mutable context to reason about. - Compiled pipeline — the whole chain is assembled once into a pre-built delegate. Runtime execution does no per-call reflection or DI resolution.
- Guided type-state builder — the fluent API only offers methods that are valid at each stage (for example,
Run(out ...)appears only after you have added at least one step), so invalid pipelines fail to compile rather than at runtime. ForEachwith adaptive tuning — fan a collection out across items; on a licensed engine the concurrency tuner adjusts the degree of parallelism from observed throughput.- Sagas with compensation — group steps in
BeginSaga()/EndSaga()and attachAddStepWithCompensation(...); if a later step fails, completed steps are rolled back per yourCompensationPolicy(BestEffort,AbortOnFirst,SwallowErrors). - Resource gates — wrap side-effecting work in
.Gate(ResourceKind.Network | DiskIO | Cpu | Database, ...)(or a customResourceKind.Of("...")) to bound concurrent access to a shared resource. - Conditionals — branch inline with
.If(predicate, then, else).
Free vs. licensed
The unlicensed (free) tier runs every step correctly, but sequentially, with the concurrency tuner off. A valid license key unlocks the parallel execution engine and the adaptive / Bayesian concurrency tuner (WithTuning() / WithBayesianTuning()). The same code runs either way — the key only changes how the work is scheduled.
License & contact
Proprietary. See LICENSE.txt in the package. The free tier may be used at no cost; a commercial license key is required to enable the parallel engine and concurrency tuning.
Contact: dongyang.stephen.chen@gmail.com
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. 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. |
-
net8.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.