PowerPipe.Extensions.MicrosoftDependencyInjection
1.1.0-rc
See the version list below for details.
dotnet add package PowerPipe.Extensions.MicrosoftDependencyInjection --version 1.1.0-rc
NuGet\Install-Package PowerPipe.Extensions.MicrosoftDependencyInjection -Version 1.1.0-rc
<PackageReference Include="PowerPipe.Extensions.MicrosoftDependencyInjection" Version="1.1.0-rc" />
paket add PowerPipe.Extensions.MicrosoftDependencyInjection --version 1.1.0-rc
#r "nuget: PowerPipe.Extensions.MicrosoftDependencyInjection, 1.1.0-rc"
// Install PowerPipe.Extensions.MicrosoftDependencyInjection as a Cake Addin #addin nuget:?package=PowerPipe.Extensions.MicrosoftDependencyInjection&version=1.1.0-rc&prerelease // Install PowerPipe.Extensions.MicrosoftDependencyInjection as a Cake Tool #tool nuget:?package=PowerPipe.Extensions.MicrosoftDependencyInjection&version=1.1.0-rc&prerelease
PowerPipe: A .NET Library for Constructing Advanced Pipelines with Fluent Interface
PowerPipe is a versatile .NET library designed to streamline the process of building advanced pipelines using a fluent interface. The primary objective of this project is to eliminate the need for writing boilerplate code when implementing pipelines.
Table of Contents
- Features and Benefits
- Installation
- Core Components
- Pipeline Steps: Building Blocks of Pipelines
- PipelineStepFactory: Step Factory for Dependency Injection
- PipelineBuilder: Building Pipelines
- Extensions: Microsoft Dependency Injection
- Examples
- Contributors are Welcome!
Features and Benefits
- Developed using .NET 6 for optimal performance and compatibility.
- Offers a readable and intuitive API that simplifies pipeline construction.
Installation
You can easily integrate PowerPipe into your project by installing the required NuGet packages. Use the following commands in the Package Manager Console or .NET CLI:
Package Manager Console
Install-Package PowerPipe
Install-Package PowerPipe.Extensions.MicrosoftDependencyInjection
.NET CLI
dotnet add package PowerPipe
dotnet add package PowerPipe.Extensions.MicrosoftDependencyInjection
Core Components
PipelineContext: Abstract Context Class
PipelineContext
serves as the foundational abstract context class from which all specific contexts should inherit. It provides a generic representation that encapsulates the outcome of the pipeline.
public abstract class PipelineContext<TResult>
where TResult : class
{
public abstract TResult GetPipelineResult();
}
Pipeline: Constructing Pipelines
The Pipeline
class represents a generic pipeline implementation. It is responsible for connecting all pipeline steps internally and executing the initial step to kickstart the process.
public class Pipeline<TContext, TResult> : IPipeline<TResult>
where TContext : PipelineContext<TResult>
where TResult : class
{
// Implementation details...
}
Pipeline Methods
RunAsync
public async Task<TResult> RunAsync(CancellationToken cancellationToken, bool returnResult = true)
The RunAsync
method is the primary entry point for executing the pipeline. It allows you to specify whether you need the result of the pipeline or not. For nested pipelines, the returnResult
parameter should be set to false
.
Pipeline Steps: Building Blocks of Pipelines
IPipelineStep Interface
The IPipelineStep
interface defines the blueprint for creating custom pipeline steps. You should implement this interface to describe your own pipeline steps.
public interface IPipelineStep<TContext>
{
IPipelineStep<TContext> NextStep { get; set; }
Task ExecuteAsync(TContext context, CancellationToken cancellationToken);
}
IPipelineParallelStep Interface
The IPipelineParallelStep
interface defines the blueprint for creating custom parallel pipeline steps.
public interface IPipelineParallelStep<TContext>
{
Task ExecuteAsync(TContext context, CancellationToken cancellationToken);
}
ExecuteAsync Method
The ExecuteAsync
method is the core logic execution point for a pipeline step.
IPipelineCompensationStep Interface
The IPipelineParallelStep
interface defines the blueprint for creating custom compensation steps.
public interface IPipelineCompensationStep<TContext>
{
Task CompensateAsync(TContext context, CancellationToken cancellationToken);
}
Pre-implemented Steps
Several steps are implemented and executed internally, contributing to the pipeline flow. While they are abstracted away, it's beneficial to be aware of them.
InternalStep: An abstract class that is base for all internal steps.
LazyStep: A step that acts as a 'decorator' for other steps, ensuring thread safety.
AddIfStep: Adds a step to the main pipeline based on a specified predicate.
AddIfElseStep: Adds a step to the pipeline conditionally, branching based on a predicate.
IfPipelineStep: Adds a nested pipeline based on a predicate.
CompensationStep: Adds compensation step and handles compensation of parent steps.
ParallelStep: Adds step that handles parallel step execution.
FinishStep: Automatically added as the final step of the pipeline.
PipelineStepFactory: Step Factory for Dependency Injection
The PipelineStepFactory
class implements the IPipelineStepFactory
interface, responsible for obtaining steps from Dependency Injection (DI).
public class PipelineStepFactory : IPipelineStepFactory
{
// Implementation details...
}
PipelineBuilder: Building Pipelines
The PipelineBuilder
class is the primary tool for constructing pipelines. It allows you to define the sequence of steps and their conditions.
public sealed class PipelineBuilder<TContext, TResult>
where TContext : PipelineContext<TResult>
where TResult : class
{
// Implementation details...
}
PipelineBuilder Methods
Add
public PipelineBuilder<TContext, TResult> Add<T>()
where T : IPipelineStep<TContext>
The Add
method appends a step to the end of the pipeline.
AddIf
public PipelineBuilder<TContext, TResult> AddIf<T>(Predicate<TContext> predicate)
where T : IPipelineStep<TContext>
The AddIf
method adds a step to the pipeline based on a specified predicate.
If
public PipelineBuilder<TContext, TResult> If(Func<bool> predicate, Func<PipelineBuilder<TContext, TResult>, PipelineBuilder<TContext, TResult>> action)
The If
method adds a nested pipeline based on a predicate.
If (with context)
public PipelineBuilder<TContext, TResult> If(Func<TContext, bool> predicate, Func<PipelineBuilder<TContext, TResult>, PipelineBuilder<TContext, TResult>> action)
Similar to the previous method, the If
method adds a nested pipeline, but this time it accepts a predicate with access to the TContext
object.
OnError
public PipelineBuilder<TContext, TResult> OnError(PipelineStepErrorHandling errorHandling, TimeSpan? retryInterval = null, int? maxRetryCount = null, Predicate<TContext> predicate = null)
The OnError
method adds error-handling behavior to the step. Currently available error handling behaviors: Suppress
- suppress error and proceed to next step; Retry
- retry step execution.
Optional parameters:
retryInterval
- interval between retries; default value - 1 second.
maxRetryCount
- retries count; default value - 1.
predicate
- context-based predicate that indicates whether error handling should apply or not.
CompensateWith
public PipelineBuilder<TContext, TResult> CompensateWith<T>()
The CompensateWith
method adds compensation step to the previous added step in pipeline.
Note! That
CompensationWith
method can be applied to the internal pipeline step as well for the whole internal pipeline
Parallel
public PipelineBuilder<TContext, TResult> Parallel(Func<PipelineBuilder<TContext, TResult>, PipelineBuilder<TContext, TResult>> action, int maxDegreeOfParallelism = -1)
The Parallel
method adds a nested pipeline that is responsible for adding steps for parallel execution.
Build
public IPipeline<TResult> Build()
The Build
method finalizes the pipeline construction by adding a FinishStep<TContext>
and returning the built pipeline as an IPipeline<TResult>
object.
Extensions: Microsoft Dependency Injection
The PowerPipe.Extensions.MicrosoftDependencyInjection
extension provides integration with Microsoft Dependency Injection.
Methods
AddPowerPipe
public static IServiceCollection AddPowerPipe(this IServiceCollection serviceCollection)
The AddPowerPipe
method adds the IPipelineStepFactory
to the Dependency Injection container.
AddPowerPipeStep
public static IServiceCollection AddPowerPipeStep<TStep, TContext>(this IServiceCollection serviceCollection, ServiceLifetime lifetime = ServiceLifetime.Transient)
where TStep : class, IPipelineStep<TContext>
where TContext : PipelineContext<Type>
The AddPowerPipeStep
method adds your custom pipeline steps to the Dependency Injection container with a transient scope by default.
AddPowerPipeCompensationStep
public static IServiceCollection AddPowerPipeCompensationStep<TStep, TContext>(this IServiceCollection serviceCollection, ServiceLifetime lifetime = ServiceLifetime.Transient)
where TStep : class, IPipelineCompensationStep<TContext>
where TContext : class
The AddPowerPipeStep
method adds your custom pipeline steps to the Dependency Injection container with a transient scope by default.
Examples
Example: Processing Customer Orders
Suppose you're working on an e-commerce platform, and you need to process incoming customer orders. Each order involves several steps, such as validation, pricing calculation, and inventory management. Let's see how PowerPipe can help you build a pipeline to handle this process.
Step 1: Define the Pipeline Context
First, let's create a pipeline context that will hold the information related to the order processing. We'll define a simple context class that contains order details:
public class OrderContext : PipelineContext<OrderResult>
{
// Properties and methods specific to the context
}
Step 2: Implement Pipeline Steps
Next, we'll create individual steps for our pipeline. For simplicity, let's focus on two steps: validation and pricing calculation. We'll implement these steps by implementing the IPipelineStep<OrderContext> interface:
public class ValidationStep : IPipelineStep<OrderContext>
{
public IPipelineStep<OrderContext> NextStep { get; set; }
public async Task ExecuteAsync(OrderContext context, CancellationToken cancellationToken)
{
// Validate the order and update the context
// Implement your validation logic here
}
}
public class PricingStep : IPipelineStep<OrderContext>
{
public IPipelineStep<OrderContext> NextStep { get; set; }
public async Task ExecuteAsync(OrderContext context, CancellationToken cancellationToken)
{
// Calculate pricing for the order and update the context
// Implement your pricing logic here
}
}
Step 3: Build the Pipeline
Now, let's use PowerPipe to build our pipeline. We'll create a pipeline builder and add our steps to it based on certain conditions:
var pipeline = new PipelineBuilder<OrderContext, OrderResult>()
.Add<ValidationStep>()
.AddIf<PricingStep>(context => context.IsValid)
.Build();
In this example, the AddIf
method adds the PricingStep only if the order is valid.
Step 4: Execute the Pipeline
Finally, we'll execute the pipeline using the RunAsync
method:
var orderContext = new OrderContext();
var orderResult = await pipeline.RunAsync(orderContext, CancellationToken cancellationToken);
Conclusion
In this example, we've explored how to use the PowerPipe library to build advanced pipelines in a .NET application. By following the steps outlined in the example, you can effectively manage complex data processing tasks with ease. PowerPipe's fluent interface and integration with Microsoft Dependency Injection make it a powerful tool for creating maintainable and reusable pipelines.
By incorporating PowerPipe into your development workflow, you can enhance the efficiency and readability of your code while tackling intricate data processing challenges. As you continue to explore the library and its features, you'll discover even more ways to leverage its capabilities in your projects.
Contributors are Welcome!
If you have any questions or suggestions, feel free to contact me at m.vorchakov97@gmail.com. I'm welcome contributions from the community to enhance and improve the PowerPipe library. Your input is highly valued!
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
-
net6.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0.0)
- PowerPipe (>= 1.1.0-rc)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
3.0.0 | 3,780 | 7/31/2024 |
3.0.0-rc1 | 56 | 7/31/2024 |
2.0.0 | 1,452 | 3/22/2024 |
2.0.0-rc2 | 301 | 2/9/2024 |
2.0.0-rc1 | 111 | 2/8/2024 |
1.2.0 | 17,386 | 11/13/2023 |
1.2.0-rc5 | 106 | 11/10/2023 |
1.2.0-rc4 | 124 | 11/9/2023 |
1.2.0-rc3 | 97 | 11/7/2023 |
1.2.0-rc2 | 94 | 11/7/2023 |
1.2.0-rc | 89 | 11/7/2023 |
1.1.2 | 341 | 9/21/2023 |
1.1.2-beta | 232 | 9/21/2023 |
1.1.1 | 142 | 9/12/2023 |
1.1.0 | 140 | 9/11/2023 |
1.1.0-rc | 136 | 9/6/2023 |
1.0.3 | 5,306 | 7/17/2023 |
1.0.2 | 11,325 | 2/8/2023 |
1.0.1 | 570 | 1/16/2023 |
1.0.0 | 306 | 1/3/2023 |
1.0.0-beta | 140 | 1/3/2023 |
0.1.10 | 4,854 | 5/10/2022 |
0.1.9 | 412 | 5/10/2022 |
0.1.8 | 422 | 5/6/2022 |
0.1.7 | 407 | 5/5/2022 |
0.1.6 | 404 | 4/21/2022 |
0.1.5 | 418 | 4/21/2022 |
0.1.4 | 403 | 4/21/2022 |
0.1.3 | 411 | 4/18/2022 |
0.1.2 | 423 | 2/14/2022 |
0.1.1 | 407 | 2/14/2022 |
0.1.0 | 459 | 2/14/2022 |