Operations pipeline start

This commit is contained in:
Mikhail Shabanov committed 2020-07-19 13:04:31 +02:00
1 parent 6c10c6c654
commit 7ffbeb6b17
19 files changed
+432 -5

No files matched your search

@@ -0,0 +1,18 @@
using System;
using System.Threading.Tasks;
namespace WotBlitzStatisticsPro.Logic.Pipeline
{
/// <summary>
/// Represents pipeline single operation
/// </summary>
public interface IOperation<TContext>
{
/// <summary>
/// Invokes the pipeline operation
/// </summary>
/// <param name="context">Pipeline context</param>
/// <param name="next">Next operation</param>
Task Invoke(TContext context, Func<TContext, Task> next);
}
}
@@ -0,0 +1,18 @@
using System;
namespace WotBlitzStatisticsPro.Logic.Pipeline
{
/// <summary>
/// Factory creates the operation instances.
/// </summary>
public interface IOperationFactory
{
/// <summary>
/// Creates new operation instance
/// </summary>
/// <typeparam name="TContext"></typeparam>
/// <param name="operationType"></param>
/// <returns></returns>
IOperation<TContext> Create<TContext>(Type operationType);
}
}
@@ -0,0 +1,21 @@
namespace WotBlitzStatisticsPro.Logic.Pipeline
{
/// <summary>
/// Represents operation pipeline
/// </summary>
public interface IPipeline<TContext>
{
/// <summary>
/// Builds the pipeline.
/// </summary>
/// <returns>First operation in pipeline.</returns>
IOperation<TContext> Build();
/// <summary>
/// Adds operation type to the pipeline
/// </summary>
/// <typeparam name="TOperation">Operation type</typeparam>
/// <returns>Pipeline instance</returns>
IPipeline<TContext> AddOperation<TOperation>() where TOperation : IOperation<TContext>;
}
}
@@ -0,0 +1,22 @@
using System;
using System.Threading.Tasks;
namespace WotBlitzStatisticsPro.Logic.Pipeline
{
public class OperationMediator<TContext>: IOperation<TContext>
{
private readonly IOperation<TContext> _current;
private readonly IOperation<TContext> _next;
public OperationMediator(IOperation<TContext> current, IOperation<TContext> next)
{
_current = current ?? throw new ArgumentNullException(nameof(current));
_next = next;
}
public Task Invoke(TContext context, Func<TContext, Task> next)
{
return _current.Invoke(context, c => _next == null ? Task.CompletedTask : _next.Invoke(c, null));
}
}
}
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace WotBlitzStatisticsPro.Logic.Pipeline
{
public class Pipeline<TContext>: IPipeline<TContext>
{
private readonly IOperationFactory _operationFactory;
private readonly List<Type> _operations = new List<Type>();
public Pipeline(IOperationFactory operationFactory)
{
_operationFactory = operationFactory;
}
public IOperation<TContext> Build()
{
var allOperationTypes = _operations.ToArray();
var lastOperationType = allOperationTypes.LastOrDefault();
if (lastOperationType == null)
{
return null;
}
var nextOperation = new OperationMediator<TContext>(_operationFactory.Create<TContext>(lastOperationType), null);
for (int i = allOperationTypes.Length - 2; i >= 0; i--)
{
nextOperation = new OperationMediator<TContext>(_operationFactory.Create<TContext>(allOperationTypes[i]), nextOperation);
}
return nextOperation;
}
public IPipeline<TContext> AddOperation<TOperation>() where TOperation : IOperation<TContext>
{
_operations.Add(typeof(TOperation));
return this;
}
}
}
@@ -0,0 +1,19 @@
using System;
namespace WotBlitzStatisticsPro.Logic.Pipeline
{
public class ServiceProviderOperationFactory: IOperationFactory
{
private readonly IServiceProvider _serviceProvider;
public ServiceProviderOperationFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IOperation<TContext> Create<TContext>(Type operationType)
{
return _serviceProvider.GetService(operationType) as IOperation<TContext>;
}
}
}