Tapeti/Tapeti/Helpers/MiddlewareHelper.cs

70 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Tapeti.Helpers
{
/// <summary>
/// Helper class for executing the middleware pattern.
/// </summary>
public static class MiddlewareHelper
{
/// <summary>
/// Executes the chain of middleware synchronously, starting with the last item in the list.
/// </summary>
/// <param name="middleware">The list of middleware to run</param>
/// <param name="handle">Receives the middleware which should be called and a reference to the action which will call the next. Pass this on to the middleware.</param>
/// <param name="lastHandler">The action to execute when the innermost middleware calls next.</param>
/// <typeparam name="T"></typeparam>
public static void Go<T>(IReadOnlyList<T> middleware, Action<T, Action> handle, Action lastHandler)
{
var handlerIndex = middleware?.Count - 1 ?? -1;
if (middleware == null || handlerIndex == -1)
{
lastHandler();
return;
}
void HandleNext()
{
handlerIndex--;
if (handlerIndex >= 0)
handle(middleware[handlerIndex], HandleNext);
else
lastHandler();
}
handle(middleware[handlerIndex], HandleNext);
}
/// <summary>
/// Executes the chain of middleware asynchronously, starting with the last item in the list.
/// </summary>
/// <param name="middleware">The list of middleware to run</param>
/// <param name="handle">Receives the middleware which should be called and a reference to the action which will call the next. Pass this on to the middleware.</param>
/// <param name="lastHandler">The action to execute when the innermost middleware calls next.</param>
/// <typeparam name="T"></typeparam>
public static async Task GoAsync<T>(IReadOnlyList<T> middleware, Func<T, Func<Task>, Task> handle, Func<Task> lastHandler)
{
var handlerIndex = middleware?.Count - 1 ?? -1;
if (middleware == null || handlerIndex == -1)
{
await lastHandler();
return;
}
async Task HandleNext()
{
handlerIndex--;
if (handlerIndex >= 0)
await handle(middleware[handlerIndex], HandleNext);
else
await lastHandler();
}
await handle(middleware[handlerIndex], HandleNext);
}
}
}