DumplingsDevs.Pipelines
1.0.1
See the version list below for details.
dotnet add package DumplingsDevs.Pipelines --version 1.0.1
NuGet\Install-Package DumplingsDevs.Pipelines -Version 1.0.1
<PackageReference Include="DumplingsDevs.Pipelines" Version="1.0.1" />
paket add DumplingsDevs.Pipelines --version 1.0.1
#r "nuget: DumplingsDevs.Pipelines, 1.0.1"
// Install DumplingsDevs.Pipelines as a Cake Addin #addin nuget:?package=DumplingsDevs.Pipelines&version=1.0.1 // Install DumplingsDevs.Pipelines as a Cake Tool #tool nuget:?package=DumplingsDevs.Pipelines&version=1.0.1
<p align="center"> <img src="docs/assets/pipelines_purple.svg#gh-light-mode-only" alt="Pipelines"/> <img src="docs/assets/pipelines_white.svg#gh-dark-mode-only" alt="Pipelines"/> </p>
π We belief that a good library should adapt to your application, rather than forcing your application to adapt to it. We recognize that every software project is unique and may employ different architectural patterns and designs. With Pipelines, we found a library that enables us to build our applications around our preferred patterns, rather than constraining us to rigid structures imposed by external libraries. This flexibility not only streamlines our development process but also empowers us to make design choices that best suit our specific use cases.
π‘ Pipelines empowers developers to leverage the potential of the Mediator pattern seamlessly, thanks to its flexible and adaptable foundations.
π¦ Installation
dotnet add package DumplingsDevs.Pipelines
dotnet add package DumplingsDevs.Pipelines.WrapperDispatcherGenerator
π Quick Start
1οΈβ£ Define your own types
1.1 Input
The "Input" acts as the initial parameter for Handler and Dispatcher methods, guiding the search for the relevant Handler.
<details> <summary style="color: green">π Show me code </summary>
public interface IInput<TResult> where TResult: class{ }
</details>
1.2 Handler
Handlers house the application logic and can generate both synchronous and asynchronous results.
<details> <summary style="color: green">π Show me code </summary>
public interface IHandler<in TInput, TResult> where TInput : IInput<TResult> where TResult: class
{
public Task<TResult> HandleAsync(TInput input, CancellationToken token);
}
</details>
1.3 Dispatcher
Serving as a bridge between inputs and their respective handlers, the Dispatcher ensures the appropriate Handler is triggered for a given Input.
<details> <summary style="color: green">π Show me code </summary>
public interface IDispatcher
{
public Task<TResult> SendAsync<TResult>(IInput<TResult> input, CancellationToken token) where TResult : class;
}
</details>
2οΈβ£ Implement first decorator (optional step)
Analogous to Middlewares in .NET. Think of them as layers of logic that execute before or after the handler.
<details> <summary style="color: green">π Show me code </summary>
public class LoggingDecorator<TInput, TResult> : IHandler<TInput, TResult> where TInput : IInput<TResult> where TResult : class
{
private readonly IHandler<TInput, TResult> _handler;
private readonly ILogger _logger;
public LoggingDecorator(IHandler<TInput, TResult> handler, ILogger logger)
{
_handler = handler;
_logger = logger;
}
public async Task<TResult> HandleAsync(TInput request, CancellationToken token)
{
_logger.Log(LogLevel.Information,"Executing handler for input {0}", typeof(TInput));
var result = await _handler.HandleAsync(request, token);
_logger.Log(LogLevel.Information,"Executed handler for input {0}", typeof(TInput));
return result;
}
}
</details>
3οΈβ£ Implement first handler
3.1 Input and Result
<details> <summary style="color: green">π Show me code </summary>
public record ExampleInput(string Value) : IInput<ExampleCommandResult>;
public record ExampleCommandResult(string Value);
</details>
3.2 Handler
<details> <summary style="color: green">π Show me code </summary>
public class ExampleHandler : IHandler<ExampleInput, ExampleCommandResult>
{
public Task<ExampleCommandResult> HandleAsync(ExampleInput input, CancellationToken token)
{
return Task.FromResult(new ExampleCommandResult(input.Value));
}
}
</details>
4οΈβ£ Register pipeline
In your application's initialization, such as Startup.cs
:
<b> IMPORTANT! All provided types must be specified using the typeof() method! </b>
<details> <summary style="color: green">π Show me code </summary>
var handlersAssembly = //Assembly where handlers assembly are implemented
var dispatcherAssembly = //Assembly where AddPipeline gets invoked
_services
.AddPipeline()
.AddInput(typeof(IInput<>))
.AddHandler(typeof(IHandler<,>), handlersAssembly)
.AddDispatcher<IDispatcher>(dispatcherAssembly)
.WithDecorator(typeof(LoggingDecorator<,>));
</details>
5οΈβ£ Example Usage (Fluent API .NET)
<details> <summary style="color: green">π Show me code </summary>
public static void CreateExampleEndpoint(this WebApplication app)
{
app.MapPost("/example", async (ExampleInput request, IDispatcher dispatcher, CancellationToken token) =>
{
var result = await dispatcher.SendAsync(input,token);
return Results.Ok();
});
}
</details>
π Detailed documentation
- Conventions
- Key Concepts
- Benchmarks
- Proxy vs Generated Dispatcher
- Code examples
- Configuration
- Troubleshooting
- ADR
β οΈ Limitations
- Pipelines in which multiple handlers will be handled for one input must have a
Task
orvoid
return type. - Cannot create a Pipeline that returns both generic and non-generic types.
π€ Roadmap
- ADR Documentation: Record key architectural decisions made during implementation using ADRs.
- Code Cleanup: Refine and tidy up the codebase post-MVP, paving the way for new feature development.
- Support for Nullable Results: Add functionality to handle nullable result types.
- Configurable Dispatcher Behavior: Implement configuration settings to decide if the dispatcher should throw an exception in case there's no handler for a given Input.
- Dependency Injection Scope Choice: Provide an option to decide whether or not to create a Dependency Injection Scope in Dispatchers.
- Multiple Inputs in Dispatcher: Enhance the dispatcher handle method to accept a list of inputs instead of just one.
- Parallel Pipeline: Introduce a pipeline to facilitate parallel execution of multiple handlers.
- Stream Pipeline: Implement support for streaming pipelines.
- Decorator Performance Optimization: Improve performance, especially concerning the use of
ActivatorUtilities.CreateInstance()
.
π₯π‘ The Dumplings Behind the Magic
Hey there! We're Dumplings Devs, made up of <a href="https://pl.linkedin.com/in/matwroblewski">Mateusz WrΓ³blewski</a> and <a href="https://pl.linkedin.com/in/kamil-bytner">Kamil Bytner</a>. We're passionate about software and always up for a coding challenge.
<p align="center"> <img src="docs/assets/dumplings_purple.svg#gh-light-mode-only" alt="DumplingsDevs"/> <img src="docs/assets/dumplings_white.svg#gh-dark-mode-only" alt="DumplingsDevs"/> </p>
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. 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 is compatible. 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. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Microsoft.Extensions.DependencyInjection (>= 7.0.0)
-
net5.0
- Microsoft.Extensions.DependencyInjection (>= 7.0.0)
-
net6.0
- Microsoft.Extensions.DependencyInjection (>= 7.0.0)
-
net7.0
- Microsoft.Extensions.DependencyInjection (>= 7.0.0)
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 |
---|---|---|
1.0.2 | 184 | 9/16/2023 |
1.0.1 | 182 | 9/10/2023 |
1.0.0 | 153 | 9/4/2023 |
0.0.14-alpha | 129 | 9/4/2023 |
0.0.13-alpha | 121 | 9/4/2023 |
0.0.12-alpha | 118 | 9/3/2023 |
0.0.11-alpha | 122 | 8/31/2023 |
0.0.10-alpha | 128 | 8/29/2023 |
0.0.9-alpha | 131 | 8/29/2023 |
0.0.8-alpha | 122 | 8/29/2023 |
0.0.7-alpha | 133 | 8/28/2023 |
0.0.6-alpha | 123 | 8/27/2023 |
0.0.5-alpha | 130 | 8/24/2023 |
0.0.4-alpha | 127 | 8/6/2023 |
0.0.3-alpha | 132 | 8/5/2023 |
0.0.2-alpha | 126 | 8/1/2023 |
0.0.1-alpha | 141 | 8/1/2023 |