You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+3-6Lines changed: 3 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,13 +1,12 @@
1
1
# Contributing to PipeForge
2
2
3
-
PipeForge has received lots of great feedback from the community. We've used this feedback to inform the direction of the project, and we absolutely want to keep hearing from you! **Your involvement makes the project better** by increasing the usability, quality and adoption of the project. Our goal is to be better stewards by being more responsive and transparent. Following the contribution guidelines outlined below will help us to better help you.
3
+
Community feedback is used to inform the direction of the project, and we absolutely want to hear from you! **Your involvement makes the project better** by increasing the usability, quality and adoption of the project. Our goal is to be better stewards by being more responsive and transparent. Following the contribution guidelines outlined below will help us to better help you.
4
4
5
5
# How To Get Help
6
6
7
7
A lot of issues that were created in previous versions of PipeForge were not bugs or feature requests, they were questions or discussions - most of which could be (and were) answered by anyone in the community; they're not exclusive to the maintainers. For feedback like this, there are several places where people can get all kinds of help, and we would encourage you to use them first.
8
8
9
9
- Consult the [official documentation](https://scottoffen.github.io/PipeForge).
10
-
- Take a gander at the [Samples](https://github.com/scottoffen/PipeForge/tree/main/src/Samples) project.
11
10
- Engage in our [community discussions](https://github.com/scottoffen/PipeForge/discussions).
12
11
- Ask your question on [StackOverflow](https://stackoverflow.com) using [#PipeForge](https://stackoverflow.com/questions/tagged/PipeForge?sort=newest).
13
12
@@ -27,8 +26,6 @@ Regardless of whether you are opening a bug report, asking a question on StackOv
27
26
28
27
Got an idea on how to make PipeForge better? Start or join a conversation in our [community discussions](https://github.com/scottoffen/PipeForge/discussions) and suggest your change there. **Do not open an issue on GitHub until** you have collected positive feedback about the change. Where it comes to improvements, we want to ensure we are focused on solving problems, not attacking symptoms, while remaining focused on our guiding principles: fast, unopinionated, and minimalist. In a word: simple.
29
28
30
-
That being said, PipeForge is designed to make it easy to add middleware at different places in the server and request/response pipeline. You can also create your own implementations of the different interfaces and inject them. All told, that makes it easy to take your functionality and put it in a package that can be used by others as an add-on or plugin to the core PipeForge library, rather than in the core library, if that makes more sense.
31
-
32
29
If it is decided that your idea would be a good inclusion to the core PipeForge project, create a feature request issue based on the outcome of the community discussion.
33
30
34
31
# Issue Management
@@ -71,8 +68,8 @@ Changes that are cosmetic in nature and do not add anything substantial to the s
71
68
- It creates a lot of notification noise
72
69
- It pollutes the git history
73
70
74
-
Sometimes, your editor will completely reformat a file when you save it, making numerous white space changes that, while they don't affect the code, create a lot of noise for the reviewers. If this happens, the PR will not be considered until those white space changes are removed.
71
+
Sometimes, your editor may completely reformat a file when you save it, making numerous white space changes that, while they don't affect the code, create a lot of noise for the reviewers. If this happens, the PR will not be considered until those white space changes are reverted.
75
72
76
73
# Documentation Changes
77
74
78
-
Having excellent documentation is crucial to the success of PipeForge. Documentation for PipeForge lives in [docs](). Your contribution of clear, concise and accurate documentation is appreciated.
75
+
Having excellent documentation is crucial to the success of PipeForge. Documentation for PipeForge is written using [Docusaurus](https://docusaurus.io/), lives in [docs folder](./docs/). Your contribution of clear, concise and accurate documentation is appreciated.
The `Describe()` method on `IPipelineRunner<T>` is used to inspect and document the pipeline configuration at runtime. It returns a JSON string describing each registered pipeline step.
9
+
10
+
This method is useful for diagnostics, tooling, and dynamically displaying pipeline behavior in user interfaces or logs - but only if you've taken the time to add the necessary metadata to your step classes.
11
+
12
+
## Output Format
13
+
14
+
The JSON output contains an array of objects, each representing a pipeline step with the following fields:
15
+
16
+
*`Order`: The zero-based order in which the step appears in the pipeline
17
+
*`Name`: The value of the step's `Name` property
18
+
*`Description`: The step's `Description`, if defined
19
+
*`MayShortCircuit`: A boolean indicating whether the step might short-circuit execution
20
+
*`ShortCircuitCondition`: The value of the step's `ShortCircuitCondition`, if any
21
+
22
+
Example output:
23
+
24
+
```json
25
+
[
26
+
{
27
+
"Order": 0,
28
+
"Name": "ValidateInput",
29
+
"Description": "Checks that required values are present",
30
+
"MayShortCircuit": true,
31
+
"ShortCircuitCondition": "Invalid input"
32
+
},
33
+
{
34
+
"Order": 1,
35
+
"Name": "TransformData",
36
+
"Description": "Prepares data for downstream steps",
37
+
"MayShortCircuit": false,
38
+
"ShortCircuitCondition": null
39
+
}
40
+
]
41
+
```
42
+
43
+
## Instantiation Behavior
44
+
45
+
Calling `Describe()`**will instantiate all steps** in the pipeline by accessing their `Lazy<T>` wrappers. This may result in constructor injection or other side effects associated with instantiating the step class. Use this method only when you are prepared for that overhead.
46
+
47
+
## Use Cases
48
+
49
+
* Logging pipeline structure for observability
50
+
* Generating runtime documentation or UI
51
+
* Verifying step order and metadata during tests or builds
52
+
53
+
If you need to inspect step configuration without triggering instantiation, consider maintaining parallel metadata or restricting usage of `Describe()` to controlled environments.
54
+
55
+
## Conclusion
56
+
57
+
Use `Describe()` to introspect your pipeline at runtime, but be aware that it will force full resolution of every registered step.
PipeForge includes built-in diagnostics via the [`System.Diagnostics.DiagnosticSource`](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.diagnosticsource) API. This allows you to observe pipeline execution without modifying your steps.
9
+
10
+
## Emitted Events
11
+
12
+
The pipeline emits the following diagnostic events for each step:
* You can use this mechanism to generate timing metrics, debug issues, or visualize step execution.
44
+
* Diagnostic events are low-overhead and safe to leave enabled in production.
45
+
* Combine this with the `Describe()` method for a full picture of pipeline structure and execution behavior.
46
+
47
+
## Conclusion
48
+
49
+
PipeForge diagnostics give you deep visibility into pipeline execution with minimal effort. Whether you’re debugging a failing step or building runtime instrumentation, the diagnostics hooks are ready to help.
PipeForge is a lightweight, composable, lazy-instantiation pipeline framework for .NET. It simplifies step-based processing while remaining discoverable and testable. Inspired by middleware pipelines and modern dependency injection patterns, PipeForge gives you structured control over sequential logic flows - without the ceremony.
9
+
10
+
Pipelines operate on a specific class known as the **context**. Each pipeline step is a discrete unit of work, written in code and annotated with metadata indicating its order and (optional) environment. These steps are lazily instantiated and executed in sequence by the pipeline runner.
11
+
12
+
At any point, the pipeline can **short-circuit**, halting execution — and preventing the instantiation of any remaining steps.
13
+
14
+
## Sample Context
15
+
16
+
For the purposes of this documentation, the following sample context will be used.
17
+
18
+
```csharp title="SampleContext.cs"
19
+
publicclassSampleContext
20
+
{
21
+
privatereadonlyList<string> _steps=new();
22
+
23
+
publicvoidAddStep(stringstepName)
24
+
{
25
+
if (string.IsNullOrWhiteSpace(stepName))
26
+
{
27
+
thrownewArgumentException("Step name cannot be null or whitespace.", nameof(stepName));
28
+
}
29
+
30
+
_steps.Add(stepName);
31
+
}
32
+
33
+
publicintStepCount=>_steps.Count;
34
+
35
+
publicoverridestringToString()
36
+
{
37
+
returnstring.Join(",", _steps);
38
+
}
39
+
}
40
+
```
41
+
42
+
This context allows us to:
43
+
- Track pipeline progress via AddStep()
44
+
- Print execution history using ToString()
45
+
- Assert how many steps ran using StepCount
46
+
- Simulate errors by passing invalid step names
47
+
48
+
## Installation
49
+
50
+
PipeForge is available on [NuGet.org](https://www.nuget.org/packages/PipeForge/) and can be installed using a NuGet package manager or the .NET CLI.
51
+
52
+
PipeForge targets `.NET Standard 2.0` for broad compatibility, and also multi-targets `.NET 5.0` to take advantage of modern runtime features where available.
PipeForge is designed to integrate smoothly with dependency injection, but it's flexible enough to be used without it. Manual wiring may be useful in testing scenarios, lightweight environments, or when you want full control over pipeline composition.
9
+
10
+
## Manually Constructing a Pipeline
11
+
12
+
You can manually create a list of steps and pass them to a `PipelineRunner<T>`. Each step should be wrapped in a `Lazy<IPipelineStep<T>>` to maintain compatibility with PipeForge's lazy instantiation pattern.
Manual wiring allows you to build and run a pipeline without relying on a DI container. While this approach is less common for production use, it provides maximum control for testing and minimal-host scenarios.
0 commit comments