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