using MessageFlow;
namespace MessageFlow.Samples;
///
/// Glues two independently authored chain fragments into a single chain.
///
public static class MergedChainsSample
{
///
/// Builds the fragment owned by the billing team.
///
/// The billing fragment.
public static ChainBuilder BuildBillingFragment()
=> Chain.Create()
.Use(new RefundHandler());
///
/// Builds the fragment owned by the accounts team.
///
/// The accounts fragment.
public static ChainBuilder BuildAccountsFragment()
=> Chain.Create()
.Use(new PasswordResetHandler());
///
/// Merges both fragments into one chain. Tickets neither fragment accepts fall through to the
/// fallback of the merged chain.
///
/// The composed chain.
public static IChain BuildChain()
=> Chain.Create()
.Use(BuildBillingFragment())
.Use(BuildAccountsFragment())
.WithFallback((request, _) => new ValueTask($"escalated ticket {request.Id} to a human"))
.Build();
///
/// Runs the sample against one ticket of every kind.
///
/// The writer receiving the sample output.
/// A token used to cancel the operation.
/// The triage decisions, in ticket order.
public static async Task> RunAsync(
TextWriter output,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(output);
var chain = BuildChain();
var tickets = new[]
{
new Ticket(11, TicketKind.Refund),
new Ticket(12, TicketKind.PasswordReset),
new Ticket(13, TicketKind.Other),
};
var results = new List();
foreach (var ticket in tickets)
{
var response = await chain.ExecuteAsync(ticket, cancellationToken).ConfigureAwait(false);
results.Add(response);
await output.WriteLineAsync($"ticket {ticket.Id} ({ticket.Kind}) => {response}").ConfigureAwait(false);
}
return results;
}
}