using MessageFlow;
namespace MessageFlow.Samples;
///
/// Shows middleware-style handlers that run code before and after the rest of the chain.
///
public static class MiddlewareSample
{
///
/// Builds a chain that logs every request, upper-cases the response of the inner chain and
/// answers greetings.
///
/// Receives one entry per middleware step.
/// The composed chain.
public static IChain BuildChain(ICollection log)
{
ArgumentNullException.ThrowIfNull(log);
return Chain.Create()
.Use(async (request, next, cancellationToken) =>
{
log.Add($"before:{request}");
var response = await next(request, cancellationToken).ConfigureAwait(false);
log.Add($"after:{response}");
return response;
})
.Use(async (request, next, cancellationToken) =>
{
var response = await next(request, cancellationToken).ConfigureAwait(false);
return response.ToUpperInvariant();
})
.UseWhen(
request => request.StartsWith("hello", StringComparison.OrdinalIgnoreCase),
(request, _) => new ValueTask($"greeting handled: {request}"))
.WithFallback((request, _) => new ValueTask($"echo: {request}"))
.Build();
}
///
/// Runs the sample for a greeting and for an unrelated request.
///
/// The writer receiving the sample output.
/// A token used to cancel the operation.
/// The middleware log produced by both requests.
public static async Task> RunAsync(
TextWriter output,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(output);
var log = new List();
var chain = BuildChain(log);
foreach (var request in new[] { "hello world", "ping" })
{
var response = await chain.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
await output.WriteLineAsync($"{request} => {response}").ConfigureAwait(false);
}
foreach (var entry in log)
{
await output.WriteLineAsync($" log: {entry}").ConfigureAwait(false);
}
return log;
}
}