Skip to content

scottoffen/pipeforge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PipeForge

docs NuGet MIT Target1 Target1 Contributor Covenant

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.

Installation

PipeForge is available on NuGet.org and can be installed using a NuGet package manager or the .NET CLI.

Usage

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.

Create Your Context

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);
    }
}

Create Your 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);
    }
}

Use Dependency Injection

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>();

Execute Pipeline

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!"
    }
}

Support

  • 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.

Contributing

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.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Test Coverage

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.

License

PipeForge is licensed under the MIT license.

Using PipeForge? We'd Love To Hear About It!

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!

About

.NET processing pipeline library featuring automatic step discovery and lazy execution.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages