diff --git a/src/Tests/PipelineTests.cs b/src/Tests/PipelineTests.cs index c9c99d5..e4f76e8 100644 --- a/src/Tests/PipelineTests.cs +++ b/src/Tests/PipelineTests.cs @@ -31,6 +31,7 @@ public async Task CanBuildDecoratingPipeline() called = true; return inner.HandleAsync(message, cancellation); }) + .Use(handler => WhatsAppHandler.Skip) .Build(); await pipeline.HandleAsync(new ReactionMessage("1234", service, user, 0, "🗽")); diff --git a/src/WhatsApp/WhatsAppHandler.cs b/src/WhatsApp/WhatsAppHandler.cs index e36f028..116da0f 100644 --- a/src/WhatsApp/WhatsAppHandler.cs +++ b/src/WhatsApp/WhatsAppHandler.cs @@ -6,13 +6,28 @@ public static class WhatsAppHandler { /// - /// An empty implementation of that does nothing. + /// An empty implementation of that does nothing and + /// can be used to shortcircuit the processing of WhatsApp messages. /// public static IWhatsAppHandler Empty { get; } = new EmptyWhatsAppHandler(); + /// + /// An empty implementation of that is skipped + /// when building the processing pipeline. It's useful to implement conditional + /// Use(..) logic that is dependent on runtime conditions, such as the + /// hosting environment or configuration settings. + /// + public static IWhatsAppHandler Skip { get; } = new SKipWhatsAppHandler(); + class EmptyWhatsAppHandler : IWhatsAppHandler { public IAsyncEnumerable HandleAsync(IEnumerable messages, CancellationToken cancellation = default) => AsyncEnumerable.Empty(); } + + class SKipWhatsAppHandler : IWhatsAppHandler + { + public IAsyncEnumerable HandleAsync(IEnumerable messages, CancellationToken cancellation = default) + => throw new NotSupportedException("This handler should never be invoked by the pipeline."); + } } diff --git a/src/WhatsApp/WhatsAppHandlerBuilder.cs b/src/WhatsApp/WhatsAppHandlerBuilder.cs index f7d4241..aec47bd 100644 --- a/src/WhatsApp/WhatsAppHandlerBuilder.cs +++ b/src/WhatsApp/WhatsAppHandlerBuilder.cs @@ -47,13 +47,17 @@ public IWhatsAppHandler Build(IServiceProvider? services = default) { for (var i = factories.Count - 1; i >= 0; i--) { - handler = factories[i](handler!, services); - if (handler is null) + var current = factories[i](handler!, services); + if (current is null) { Throw.InvalidOperationException( $"The {nameof(WhatsAppHandlerBuilder)} entry at index {i} returned null. " + $"Ensure that the callbacks passed to {nameof(Use)} return non-null {nameof(IWhatsAppHandler)} instances."); } + + // Only keep non-skipping handlers. + if (current != WhatsAppHandler.Skip) + handler = factories[i](handler!, services); } }