PipeForge is a lightweight, composable pipeline framework for .NET. It makes step-based processing simple, discoverable, and testable. Inspired by middleware pipelines and modern dependency injection patterns, PipeForge gives you structured control over sequential logic flows - without the ceremony.
PipeForge is available on NuGet.org and can be installed using a NuGet package manager or the .NET CLI.
Pipelines are designed to operate on specific class, referred to as the context. Multiple pipeline steps are created in code to operate on that context. Steps are annotated with an attribute indicating the order in which they should be executed. Finally, the pipeline runner is given an instance of the context to run against.
The following example uses dependency injection, and is the recommended approach to using PipeForge. For more advanced scenarios, see the full documentation.
Note
I'm suffixing my context class with the word Context
, and my steps with the word Step
for demonstration purposes only.
public class SampleContext
{
private readonly List<string> _steps = new();
public void AddStep(string stepName)
{
if (string.IsNullOrWhiteSpace(stepName))
{
throw new ArgumentException("Step name cannot be null or whitespace.", nameof(stepName));
}
_steps.Add(stepName);
}
public int StepCount => _steps.Count;
public override string ToString()
{
return string.Join("", _steps);
}
}
[PipelineStep(1)]
public class HelloStep : PipelineStep<SampleContext>
{
public override async Task InvokeAsync(SampleContext context, PipelineDelegate<SampleContext> next, CancellationToken cancellationToken = default)
{
context.AddStep("Hello");
await next(context, cancellationToken);
}
}
[PipelineStep(2)]
public class WorldStep : PipelineStep<SampleContext>
{
public override async Task InvokeAsync(SampleContext context, PipelineDelegate<SampleContext> next, CancellationToken cancellationToken = default)
{
context.AddStep("World");
await next(context, cancellationToken);
}
}
[PipelineStep(3)]
public class PunctuationStep : PipelineStep<SampleContext>
{
public override async Task InvokeAsync(SampleContext context, PipelineDelegate<SampleContext> next, CancellationToken cancellationToken = default)
{
context.AddStep("1");
await next(context, cancellationToken);
}
}
The extension method will discover and register all steps for the given T
context, as well as register an instance of IPipelineRunner<T>
that can be injected into services.
services.AddPipelineFor<SampleContext>();
Get an instance of IPipelineRunnere<SampleContext>
from your dependency injection container.
public class SampleService
{
private readonly IPipelineRunner<SampleContext> _pipelineRunner;
public SampleService(IPipelineRunner<SampleContext> pipelineRunner)
{
_pipelineRunner = pipelineRunner;
}
public async Task RunPipeline(SampleContext context, CancellationToken? token = default)
{
await _pipelineRunner.ExecuteAsync(context, token);
var result = context.ToString();
// result = "HelloWorld!"
}
}
-
Check out the project documentation https://scottoffen.github.io/pipeforge.
-
Engage in our community discussions for Q&A, ideas, and show and tell!
-
Have a question you can't find an answer for in the documentation or discussions? You can ask your questions on StackOverflow using #pipeforge. Make sure you include the version of PipeForge you are using, the platform you using it on, code samples and any specific error messages you are seeing.
-
Issues created to ask "how to" questions will be closed.
We welcome contributions from the community! In order to ensure the best experience for everyone, before creating an issue or submitting a pull request, please see the contributing guidelines and the code of conduct. Failure to adhere to these guidelines can result in significant delays in getting your contributions included in the project.
We use SemVer for versioning. For the versions available, see the tags on this repository.
You can generate and open a test coverage report by running the following command in the project root:
pwsh ./test-coverage.ps1
Note
This is a Powershell script. You must have Powershell installed to run this command. The command depends on the global installation of the dotnet tool ReportGenerator.
PipeForge is licensed under the MIT license.
Few thing are as satisfying as hearing that your open source project is being used and appreciated by others. Jump over to the discussion boards and share the love!