You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.1 KiB
73 lines
2.1 KiB
3 months ago
|
using System.Collections.Generic;
|
||
|
using Microsoft.Extensions.Logging;
|
||
|
|
||
|
namespace CellularManagement.WebSocket.Pipeline;
|
||
|
|
||
|
public class PipelineBuilder<TInput, TOutput>
|
||
|
{
|
||
|
private readonly List<IPipelineStep<TInput, TOutput>> _steps = new();
|
||
|
private readonly ILoggerFactory _loggerFactory;
|
||
|
|
||
|
public PipelineBuilder(ILoggerFactory loggerFactory)
|
||
|
{
|
||
|
_loggerFactory = loggerFactory;
|
||
|
}
|
||
|
|
||
|
public PipelineBuilder<TInput, TOutput> AddStep(IPipelineStep<TInput, TOutput> step)
|
||
|
{
|
||
|
if (step == null)
|
||
|
{
|
||
|
throw new ArgumentNullException(nameof(step));
|
||
|
}
|
||
|
_steps.Add(step);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
public IPipelineStep<TInput, TOutput> Build()
|
||
|
{
|
||
|
if (_steps.Count == 0)
|
||
|
{
|
||
|
throw new InvalidOperationException("Pipeline must have at least one step");
|
||
|
}
|
||
|
return new Pipeline<TInput, TOutput>(_steps, _loggerFactory.CreateLogger<Pipeline<TInput, TOutput>>());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public class Pipeline<TInput, TOutput> : IPipelineStep<TInput, TOutput>
|
||
|
{
|
||
|
private readonly IReadOnlyList<IPipelineStep<TInput, TOutput>> _steps;
|
||
|
private readonly ILogger<Pipeline<TInput, TOutput>> _logger;
|
||
|
|
||
|
public Pipeline(IReadOnlyList<IPipelineStep<TInput, TOutput>> steps, ILogger<Pipeline<TInput, TOutput>> logger)
|
||
|
{
|
||
|
_steps = steps;
|
||
|
_logger = logger;
|
||
|
}
|
||
|
|
||
|
public async Task<TOutput> ProcessAsync(TInput input, CancellationToken cancellationToken)
|
||
|
{
|
||
|
var current = input;
|
||
|
TOutput output = default!;
|
||
|
|
||
|
foreach (var step in _steps)
|
||
|
{
|
||
|
output = await step.ProcessAsync(current, cancellationToken);
|
||
|
current = (TInput)(object)output!;
|
||
|
}
|
||
|
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
public async Task<TOutput> ProcessWithErrorHandlingAsync(TInput input, CancellationToken cancellationToken)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
return await ProcessAsync(input, cancellationToken);
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
_logger.LogError(ex, "Error in pipeline processing");
|
||
|
throw new PipelineException("Pipeline processing failed", ex);
|
||
|
}
|
||
|
}
|
||
|
}
|