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

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);
}
}
}