Skip to content

Commit 044e9b7

Browse files
Added support for asynchronous pipelines
1 parent 9e81199 commit 044e9b7

11 files changed

Lines changed: 373 additions & 1 deletion
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace FluentPipelines.Async
5+
{
6+
/// <summary>
7+
/// An asynchronous pipeline that takes <typeparamref name="TIn"/> as input, and has no output.
8+
/// </summary>
9+
/// <typeparam name="TIn">The type of data used as input to the pipeline.</typeparam>
10+
public class AsyncInPipeline<TIn> : IAsyncInPipeline<TIn>
11+
{
12+
/// <summary>
13+
/// Gets the chain of delegates making up the steps of the pipeline.
14+
/// </summary>
15+
protected Func<TIn, Task> Chain { get; }
16+
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="AsyncInPipeline{TIn}"/> class.
19+
/// </summary>
20+
/// <param name="chain">The chain of delegates making up the steps of the pipeline.</param>
21+
public AsyncInPipeline(Func<TIn, Task> chain)
22+
{
23+
Chain = chain ?? throw new ArgumentNullException(nameof(chain));
24+
}
25+
26+
/// <inheritdoc/>
27+
public virtual Task RunAsync(TIn input)
28+
{
29+
return Chain(input);
30+
}
31+
}
32+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace FluentPipelines.Async
5+
{
6+
/// <summary>
7+
/// An asynchronous pipeline that takes <typeparamref name="TIn"/> as input, and returns <typeparamref name="TOut"/>.
8+
/// </summary>
9+
/// <typeparam name="TIn">The type of data used as input to the pipeline.</typeparam>
10+
/// <typeparam name="TOut">The type of data returned from the pipeline.</typeparam>
11+
public class AsyncPipeline<TIn, TOut> : IAsyncPipeline<TIn, TOut>
12+
{
13+
/// <summary>
14+
/// Gets the chain of delegates making up the steps of the pipeline.
15+
/// </summary>
16+
protected Func<TIn, Task<TOut>> Chain { get; }
17+
18+
/// <summary>
19+
/// Initializes a new instance of the <see cref="AsyncPipeline{TIn, TOut}"/> class.
20+
/// </summary>
21+
/// <param name="chain">The chain of delegates making up the steps of the pipeline.</param>
22+
public AsyncPipeline(Func<TIn, Task<TOut>> chain)
23+
{
24+
Chain = chain ?? throw new ArgumentNullException(nameof(chain));
25+
}
26+
27+
/// <inheritdoc/>
28+
public virtual Task<TOut> RunAsync(TIn input)
29+
{
30+
return Chain(input);
31+
}
32+
}
33+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace FluentPipelines.Async
5+
{
6+
/// <summary>
7+
/// An asynchronous pipeline that takes no input, and returns <typeparamref name="TOut"/>.
8+
/// </summary>
9+
/// <typeparam name="TOut">The type of data returned from the pipeline.</typeparam>
10+
public class AsyncPipeline<TOut> : IAsyncPipeline<TOut>
11+
{
12+
/// <summary>
13+
/// Gets the chain of delegates making up the steps of the pipeline.
14+
/// </summary>
15+
protected Func<Task<TOut>> Chain { get; }
16+
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="AsyncPipeline{TOut}"/> class.
19+
/// </summary>
20+
/// <param name="chain">The chain of delegates making up the steps of the pipeline.</param>
21+
public AsyncPipeline(Func<Task<TOut>> chain)
22+
{
23+
Chain = chain ?? throw new ArgumentNullException(nameof(chain));
24+
}
25+
26+
/// <inheritdoc/>
27+
public virtual Task<TOut> RunAsync()
28+
{
29+
return Chain();
30+
}
31+
}
32+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace FluentPipelines.Async
5+
{
6+
/// <summary>
7+
/// An asynchronous pipeline with no input nor no output.
8+
/// </summary>
9+
public partial class AsyncPipeline : IAsyncPipeline
10+
{
11+
/// <summary>
12+
/// Gets the chain of delegates making up the steps of the pipeline.
13+
/// </summary>
14+
protected Func<Task> Chain { get; }
15+
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="AsyncPipeline"/> class.
18+
/// </summary>
19+
/// <param name="chain">The chain of delegates making up the steps of the pipeline.</param>
20+
public AsyncPipeline(Func<Task> chain)
21+
{
22+
Chain = chain ?? throw new ArgumentNullException(nameof(chain));
23+
}
24+
25+
/// <inheritdoc/>
26+
public virtual Task RunAsync()
27+
{
28+
return Chain();
29+
}
30+
}
31+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace FluentPipelines.Async
5+
{
6+
/// <summary>
7+
/// A builder that builds an asynchronous pipeline with input data and no output data.
8+
/// </summary>
9+
/// <typeparam name="TIn">The type of data used as input to the pipeline.</typeparam>
10+
public class AsyncInPipelineBuilder<TIn> : IAsyncInPipelineBuilder<TIn>
11+
{
12+
/// <summary>
13+
/// Gets the chain of delegates making up the steps of the pipeline.
14+
/// </summary>
15+
protected Func<TIn, Task> Chain { get; }
16+
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="AsyncInPipelineBuilder{TIn}"/> class.
19+
/// </summary>
20+
/// <param name="chain">The chain of delegates making up the steps which will be used to construct the pipeline.</param>
21+
public AsyncInPipelineBuilder(Func<TIn, Task> chain)
22+
{
23+
Chain = chain ?? throw new ArgumentNullException(nameof(chain));
24+
}
25+
26+
/// <inheritdoc/>
27+
public virtual IAsyncInPipeline<TIn> Build()
28+
{
29+
return new AsyncInPipeline<TIn>(Chain);
30+
}
31+
}
32+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace FluentPipelines.Async
5+
{
6+
/// <summary>
7+
/// A builder that builds an asynchronous pipeline with input and output data.
8+
/// </summary>
9+
/// <typeparam name="TIn">The type of data used as input to the pipeline.</typeparam>
10+
/// <typeparam name="TOut">The type of data returned from the pipeline.</typeparam>
11+
public class AsyncPipelineBuilder<TIn, TOut> : IAsyncPipelineBuilder<TIn, TOut>
12+
{
13+
/// <summary>
14+
/// Gets the chain of delegates making up the steps of the pipeline.
15+
/// </summary>
16+
protected Func<TIn, Task<TOut>> Chain { get; }
17+
18+
/// <summary>
19+
/// Initializes a new instance of the <see cref="AsyncPipelineBuilder{TIn, TOut}"/> class.
20+
/// </summary>
21+
/// <param name="chain">The chain of delegates making up the steps of the pipeline.</param>
22+
public AsyncPipelineBuilder(Func<TIn, Task<TOut>> chain)
23+
{
24+
Chain = chain ?? throw new ArgumentNullException(nameof(chain));
25+
}
26+
27+
/// <inheritdoc/>
28+
public virtual IAsyncPipeline<TIn, TOut> Build()
29+
{
30+
return new AsyncPipeline<TIn, TOut>(Chain);
31+
}
32+
33+
/// <inheritdoc/>
34+
public virtual IAsyncPipelineBuilder<TIn, TNext> Then<TNext>(Func<TOut, TNext> step)
35+
{
36+
if(step is null)
37+
throw new ArgumentNullException(nameof(step));
38+
39+
return new AsyncPipelineBuilder<TIn, TNext>(async (input) => step(await Chain(input)));
40+
}
41+
42+
/// <inheritdoc/>
43+
public virtual IAsyncPipelineBuilder<TIn, TNext> Then<TNext>(Func<TOut, Task<TNext>> step)
44+
{
45+
if(step is null)
46+
throw new ArgumentNullException(nameof(step));
47+
48+
return new AsyncPipelineBuilder<TIn, TNext>(async (input) => await step(await Chain(input)));
49+
}
50+
51+
/// <inheritdoc/>
52+
public virtual IAsyncInPipelineBuilder<TIn> Then(Action<TOut> step)
53+
{
54+
if(step is null)
55+
throw new ArgumentNullException(nameof(step));
56+
57+
return new AsyncInPipelineBuilder<TIn>(async (input) => step(await Chain(input)));
58+
}
59+
60+
/// <inheritdoc/>
61+
public virtual IAsyncInPipelineBuilder<TIn> Then(Func<TOut, Task> step)
62+
{
63+
if(step is null)
64+
throw new ArgumentNullException(nameof(step));
65+
66+
return new AsyncInPipelineBuilder<TIn>(async (input) => await step(await Chain(input)));
67+
}
68+
}
69+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace FluentPipelines.Async
5+
{
6+
/// <summary>
7+
/// A builder that builds an asynchronous pipeline with output data and no input data.
8+
/// </summary>
9+
/// <typeparam name="TOut">The type of data returned from the pipeline.</typeparam>
10+
public class AsyncPipelineBuilder<TOut> : IAsyncPipelineBuilder<TOut>
11+
{
12+
/// <summary>
13+
/// Gets the chain of delegates making up the steps of the pipeline.
14+
/// </summary>
15+
protected Func<Task<TOut>> Chain { get; }
16+
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="AsyncPipelineBuilder{TOut}"/> class.
19+
/// </summary>
20+
/// <param name="chain">The chain of delegates making up the steps of the pipeline.</param>
21+
public AsyncPipelineBuilder(Func<Task<TOut>> chain)
22+
{
23+
Chain = chain ?? throw new ArgumentNullException(nameof(chain));
24+
}
25+
26+
/// <inheritdoc/>
27+
public virtual IAsyncPipeline<TOut> Build()
28+
{
29+
return new AsyncPipeline<TOut>(Chain);
30+
}
31+
32+
/// <inheritdoc/>
33+
public virtual IAsyncPipelineBuilder<TNext> Then<TNext>(Func<TOut, TNext> step)
34+
{
35+
if(step is null)
36+
throw new ArgumentNullException(nameof(step));
37+
38+
return new AsyncPipelineBuilder<TNext>(async () => step(await Chain()));
39+
}
40+
41+
/// <inheritdoc/>
42+
public virtual IAsyncPipelineBuilder<TNext> Then<TNext>(Func<TOut, Task<TNext>> step)
43+
{
44+
if(step is null)
45+
throw new ArgumentNullException(nameof(step));
46+
47+
return new AsyncPipelineBuilder<TNext>(async () => await step(await Chain()));
48+
}
49+
50+
/// <inheritdoc/>
51+
public virtual IAsyncPipelineBuilder Then(Action<TOut> step)
52+
{
53+
if(step is null)
54+
throw new ArgumentNullException(nameof(step));
55+
56+
return new AsyncPipelineBuilder(async () => step(await Chain()));
57+
}
58+
59+
/// <inheritdoc/>
60+
public virtual IAsyncPipelineBuilder Then(Func<TOut, Task> step)
61+
{
62+
if(step is null)
63+
throw new ArgumentNullException(nameof(step));
64+
65+
return new AsyncPipelineBuilder(async () => await step(await Chain()));
66+
}
67+
}
68+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace FluentPipelines.Async
5+
{
6+
/// <summary>
7+
/// A builder that builds an asynchronous pipeline with no input nor output data.
8+
/// </summary>
9+
public class AsyncPipelineBuilder : IAsyncPipelineBuilder
10+
{
11+
/// <summary>
12+
/// Gets the chain of delegates making up the steps of the pipeline.
13+
/// </summary>
14+
protected Func<Task> Chain { get; }
15+
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="AsyncPipelineBuilder"/> class.
18+
/// </summary>
19+
/// <param name="chain">The chain of delegates making up the steps of the pipeline.</param>
20+
public AsyncPipelineBuilder(Func<Task> chain)
21+
{
22+
Chain = chain ?? throw new ArgumentNullException(nameof(chain));
23+
}
24+
25+
/// <inheritdoc/>
26+
public virtual IAsyncPipeline Build()
27+
{
28+
return new AsyncPipeline(Chain);
29+
}
30+
}
31+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace FluentPipelines.Async
5+
{
6+
/// <summary>
7+
/// A builder that constructs the beginning of asynchronous pipelines with no input data.
8+
/// </summary>
9+
public class AsyncPipelineStartBuilder : IAsyncPipelineStartBuilder
10+
{
11+
/// <inheritdoc/>
12+
public virtual IAsyncPipelineBuilder<TNext> Then<TNext>(Func<TNext> step)
13+
{
14+
return new AsyncPipelineBuilder<TNext>(() => Task.FromResult(step()));
15+
}
16+
17+
/// <inheritdoc/>
18+
public virtual IAsyncPipelineBuilder<TNext> Then<TNext>(Func<Task<TNext>> step)
19+
{
20+
return new AsyncPipelineBuilder<TNext>(step);
21+
}
22+
}
23+
}

FluentPipelines/FluentPipelines.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
</ItemGroup>
4343

4444
<ItemGroup>
45-
<PackageReference Include="FluentPipelines.Abstractions" Version="1.0.1" />
45+
<PackageReference Include="FluentPipelines.Abstractions" Version="1.1.0" />
4646
</ItemGroup>
4747

4848
</Project>

0 commit comments

Comments
 (0)