{"id":15036112,"url":"https://github.com/fracerqueira/pipeandfilter","last_synced_at":"2025-12-06T04:01:32.928Z","repository":{"id":205356494,"uuid":"713995800","full_name":"FRACerqueira/PipeAndFilter","owner":"FRACerqueira","description":"Pipeline control for .NET Core with flexible conditions for each step (pipe) and the ability to parallel execute tasks over a pipe.","archived":false,"fork":false,"pushed_at":"2024-07-09T21:59:09.000Z","size":421,"stargazers_count":1,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-15T10:55:41.148Z","etag":null,"topics":["csharp","csharp-library","dotnet-core","pipe","pipefitter","pipeline","workflow"],"latest_commit_sha":null,"homepage":"https://fracerqueira.github.io/PipeAndFilter/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FRACerqueira.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"FRACerqueira"}},"created_at":"2023-11-03T17:22:15.000Z","updated_at":"2024-06-04T14:08:47.000Z","dependencies_parsed_at":"2023-11-14T18:45:17.025Z","dependency_job_id":"a5039764-159b-4b44-b5da-3af2aae18645","html_url":"https://github.com/FRACerqueira/PipeAndFilter","commit_stats":null,"previous_names":["fracerqueira/pipeandfilter"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FRACerqueira%2FPipeAndFilter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FRACerqueira%2FPipeAndFilter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FRACerqueira%2FPipeAndFilter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FRACerqueira%2FPipeAndFilter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FRACerqueira","download_url":"https://codeload.github.com/FRACerqueira/PipeAndFilter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241944961,"owners_count":20046856,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","csharp-library","dotnet-core","pipe","pipefitter","pipeline","workflow"],"created_at":"2024-09-24T20:30:10.623Z","updated_at":"2025-12-06T04:01:32.859Z","avatar_url":"https://github.com/FRACerqueira.png","language":"C#","funding_links":["https://github.com/sponsors/FRACerqueira"],"categories":[],"sub_categories":[],"readme":"# \u003cimg align=\"left\" width=\"100\" height=\"100\" src=\"./docs/images/icon.png\"\u003eWelcome to PipeAndFilter\n[![Build](https://github.com/FRACerqueira/PipeAndFilter/workflows/Build/badge.svg)](https://github.com/FRACerqueira/PipeAndFilter/actions/workflows/build.yml)\n[![License](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE)\n[![NuGet](https://img.shields.io/nuget/v/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/)\n[![Downloads](https://img.shields.io/nuget/dt/PipeAndFilter)](https://www.nuget.org/packages/PipeAndFilter/)\n\n\n### **PipeAndFilter component for .NET Core with flexible conditions for each step (pipe) and the ability to parallel execute tasks over a pipe.**\n\n**PipeAndFilter** was developed in C# with the **netstandard2.1**, **.NET 6** , **.NET 7** and **.NET 8** target frameworks.\n\n\n\u003cimg src=\"./docs/images/PipeAndFilterFeature.png\"\u003e \n\n**[Visit the official page for more documentation of PipeAndFilter](https://fracerqueira.github.io/PipeAndFilter)**\n\n## Table of Contents\n\n- [What's new - previous versions](./docs/whatsnewprev.md)\n- [Features](#features)\n- [Installing](#installing)\n- [Examples](#examples)\n- [Usage](#usage)\n- [Performance](#performance)\n- [Code of Conduct](#code-of-conduct)\n- [Contributing](#contributing)\n- [Credits](#credits)\n- [License](#license)\n- [API Reference](https://fracerqueira.github.io/PipeAndFilter/apis/apis.html)\n\n## What's new in the latest version \n### V1.0.4 \n[**Top**](#table-of-contents)\n\n- Release G.A with .NET8 \n\n## Features\n[**Top**](#table-of-contents)\n\n- Thread safety to obtain/change contract values ​​and/or generic purpose when running a Task (pararel execute)\n- Add multiple pipe\n- Add multiple Aggregate pipe (for run pararel tasks)\n- Set the maximum amount of parallel execution\n- Add multiple preconditions to run a pipe or task\n- Add multiple link to the pipe to jump to another pipe\n- Perform an action with conditions after pipe/aggregatepipe \n- Have detailed status (execution date, execution time, type of execution, result of each execution) and number of executions in each pipe\n- Save multiple results from each pipe to be used during the another pipe/aggregate pipe run\n- Save multiple results in each task to be effective during the aggregation pipe run\n- Terminate the PipeAndFilter on any task, condition or pipe\n- Simple and clear fluent syntax\n\n## Installing\n[**Top**](#table-of-contents)\n\n```\nInstall-Package PipeAndFilter [-pre]\n```\n\n```\ndotnet add package PipeAndFilter [--prerelease]\n```\n\n**_Note:  [-pre]/[--prerelease] usage for pre-release versions_**\n\n## Examples\n[**Top**](#table-of-contents)\n\nSee folder [**Samples**](https://github.com/FRACerqueira/PipeAndFilter/tree/main/Samples).\n\n```\ndotnet run --project [name of sample]\n```\n\n## Usage\n[**Top**](#table-of-contents)\n\nThe **PipeAndFilter** use **fluent interface**; an object-oriented API whose design relies extensively on method chaining. Its goal is to increase code legibility. The term was coined in 2005 by Eric Evans and Martin Fowler.\n\n### Sample-Console Usage (Full features)\n\n```csharp\nawait PipeAndFilter.New\u003cMyClass\u003e()\n    .AddPipe(Pipe1)\n        .WithGotoCondition(Cond0, \"LastPipe\")\n        .WithCondition(Cond1)\n        .WithCondition(Cond2)\n        .AfterRunningPipe(ExecPipeAfter)\n            .WithCondition(CondA1)\n            .WithGotoCondition(CondA2, \"LastPipe\")\n    .AddPipe(Pipe2)\n        .AfterRunningPipe()\n            .WithGotoCondition(CondA3, \"LastPipe\")\n    .AddPipe(Pipe3)\n        .AfterRunningAggregatePipe(ExecPipeAfterTask)\n            .MaxDegreeProcess(8)\n            .AddTaskCondition(Task50)\n                .WithCondition(CondTrue)\n            .AddTask(Task100)    \n    .AddPipe(Pipe4)\n    .AddAggregatePipe(Pipe5)\n        .WithCondition(Cond1)\n        .MaxDegreeProcess(4)\n        .AddTask(Task50)\n        .AddTaskCondition(Task100)\n            .WithCondition(Cond3)\n            .WithCondition(Cond4)\n        .AddTask(Task150)\n    .AddPipe(Pipe6, \"LastPipe\")\n    .BuildAndCreate()\n    .Init(contract)\n    .CorrelationId(null)\n    .Logger(null)\n    .Run();\n```\n\n### Sample-api/webUsage\n[**Top**](#table-of-contents)\n\n```csharp\nbuilder.Services\n    .AddPipeAndFilter(PipeAndFilter.New\u003cWeatherForecast\u003e()\n        .AddPipe(TemperatureAdd10)\n        .Build());\n```\n\n```csharp\nprivate static Task TemperatureAdd10(EventPipe\u003cWeatherForecast\u003e pipe, CancellationToken token)\n{\n    pipe.ThreadSafeAccess((contract) =\u003e\n    {\n        contract.TemperatureC += 10;\n    });\n    return Task.CompletedTask;\n}\n```\n\n```csharp\n[ApiController]\n[Route(\"[controller]\")]\npublic class WeatherForecastController : ControllerBase\n{\n    private readonly ILogger\u003cWeatherForecastController\u003e _logger;\n    private readonly IPipeAndFilterService\u003cWeatherForecast\u003e _mypipe;\n\n    public WeatherForecastController(ILogger\u003cWeatherForecastController\u003e logger, IPipeAndFilterService\u003cWeatherForecast\u003e pipeAndFilter)\n    {\n        _logger = logger;\n        _mypipes = pipeAndFilter;\n    }\n\n    [HttpGet(Name = \"GetWeatherForecast\")]\n    public async Task\u003cWeatherForecast\u003e Get(CancellationToken cancellation)\n    {\n            var cid = Guid.NewGuid().ToString();\n\n            var pipe = await _mypipes\n                .Create()\n                .Logger(_logger)\n                .CorrelationId(cid)\n                .Init(new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now), Summary = \"PipeAndFilter-Opc1\", TemperatureC = 0 })\n                .Run(cancellation);\n            return pipe.Value!\n    }\n}\n```\n\n## Performance\n[**Top**](#table-of-contents)\n\nAll pipes, conditions and tasks do not perform any task, they are only called and executed by the component\n\nSee folder [**Samples/PipeandFIlterBenchmarking**](https://github.com/FRACerqueira/PipeAndFilter/tree/main/Samples/PipeandFIlterBenchmarking).\n\n```\nBenchmarkDotNet v0.13.10, Windows 10 (10.0.19044.3570/21H2/November2021Update)\nIntel Core i7-8565U CPU 1.80GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores\n.NET SDK 8.0.100\n  [Host]     : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2\n  DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2\n\n\n| Method                       | Mean       | Error     | StdDev     | Median     | Gen0    | Allocated |\n|----------------------------- |-----------:|----------:|-----------:|-----------:|--------:|----------:|\n| PipeAsync                    |   6.043 us | 0.1453 us |  0.4240 us |   5.929 us |  0.9842 |   4.03 KB |\n| PipeWith10Async              | 219.920 us | 9.0387 us | 26.2230 us | 213.204 us | 20.7520 |  85.45 KB |\n| PipeWithConditionAsync       |   8.561 us | 0.1803 us |  0.5203 us |   8.458 us |  1.2970 |    5.3 KB |\n| PipeWith10ConditionAsync     |  54.716 us | 2.4453 us |  7.2099 us |  51.169 us |  6.4697 |  26.84 KB |\n| PipeWith10ConditionGotoAsync |  88.367 us | 2.2634 us |  6.4942 us |  88.401 us |  8.4229 |  34.75 KB |\n| PipeTaskAsync                |  16.670 us | 0.3316 us |  0.9297 us |  16.466 us |  1.5869 |   6.49 KB |\n| PipeWith10TaskAsync          | 179.862 us | 5.2544 us | 14.9910 us | 175.589 us |  7.8125 |  32.68 KB |\n| PipeTaskConditionAsync       |  20.225 us | 0.4035 us |  1.0344 us |  20.082 us |  1.8921 |   7.73 KB |\n| PipeWith10TaskConditionAsync | 183.540 us | 4.5200 us | 13.1851 us | 180.380 us |  7.8125 |  32.68 KB |\n```\n\n```\nIntel Core i7-8565U CPU 1.80GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores\n.NET SDK 8.0.100\n  [Host]     : .NET 6.0.25 (6.0.2523.51912), X64 RyuJIT AVX2\n  DefaultJob : .NET 6.0.25 (6.0.2523.51912), X64 RyuJIT AVX2\n\n\n| Method                       | Mean       | Error      | StdDev     | Median     | Gen0    | Allocated |\n|----------------------------- |-----------:|-----------:|-----------:|-----------:|--------:|----------:|\n| PipeAsync                    |   7.779 us |  0.3361 us |  0.9752 us |   7.439 us |  1.0071 |   4.13 KB |\n| PipeWith10Async              | 233.087 us | 11.3821 us | 33.2020 us | 221.658 us | 20.9961 |  86.47 KB |\n| PipeWithConditionAsync       |  10.678 us |  0.2496 us |  0.7122 us |  10.448 us |  1.3428 |   5.51 KB |\n| PipeWith10ConditionAsync     |  72.872 us |  2.1928 us |  6.1489 us |  71.057 us |  6.8359 |  27.95 KB |\n| PipeWith10ConditionGotoAsync |  94.723 us |  1.8764 us |  4.6729 us |  93.935 us |  8.7891 |  35.98 KB |\n| PipeTaskAsync                |  20.262 us |  0.5102 us |  1.4555 us |  19.804 us |  1.6174 |   6.64 KB |\n| PipeWith10TaskAsync          | 252.078 us |  4.9050 us |  6.7141 us | 250.701 us |  7.8125 |  33.21 KB |\n| PipeTaskConditionAsync       |  28.370 us |  0.9535 us |  2.7662 us |  28.128 us |  1.9531 |   7.99 KB |\n| PipeWith10TaskConditionAsync | 257.651 us |  5.1477 us |  6.5102 us | 260.074 us |  7.8125 |  33.21 KB |\n```\n\n## Code of Conduct\n[**Top**](#table-of-contents)\n\nThis project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.\nFor more information see the [Code of Conduct](CODE_OF_CONDUCT.md).\n\n## Contributing\n\nSee the [Contributing guide](CONTRIBUTING.md) for developer documentation.\n\n## Credits\n[**Top**](#table-of-contents)\n\n**API documentation generated by**\n\n- [xmldoc2md](https://github.com/FRACerqueira/xmldoc2md), Copyright (c) 2022 Charles de Vandière.\n\n## License\n[**Top**](#table-of-contents)\n\nCopyright 2023 @ Fernando Cerqueira\n\nPipeAndFilter is licensed under the MIT license. See [LICENSE](https://github.com/FRACerqueira/PipeAndFilter/blob/master/LICENSE).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffracerqueira%2Fpipeandfilter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffracerqueira%2Fpipeandfilter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffracerqueira%2Fpipeandfilter/lists"}