Intercepting Command Execution

How to use command interceptors to run logic before or after any command executes

When you need cross-cutting concerns like logging, timing, or authentication across all commands without duplicating code, implement a command interceptor. The interceptor runs before and after every command, keeping individual commands focused on their core logic.

What We're Building

A timing interceptor wrapping every command, reporting execution duration automatically—no timing code in the commands themselves:

Command interception demonstration

Create an Interceptor

Implement ICommandInterceptor with two methods: Intercept runs before execution, InterceptResult runs after. The same instance handles both, so you can store state between them.

public class TimingInterceptor : ICommandInterceptor
{
    private Stopwatch? _stopwatch;
  
    public void Intercept(CommandContext context, CommandSettings settings)
    {
        // Runs before command execution
        _stopwatch = Stopwatch.StartNew();
        System.Console.WriteLine($"Starting command: {context.Name}");
    }
  
    public void InterceptResult(CommandContext context, CommandSettings settings, ref int result)
    {
        // Runs after command execution
        _stopwatch?.Stop();
        System.Console.WriteLine($"Command completed in {_stopwatch?.ElapsedMilliseconds}ms (exit code: {result})");
    }
}

Register the Interceptor

Use SetInterceptor in your configuration:

var app = new CommandApp();
  
app.Configure(config =>
{
    config.SetInterceptor(new TimingInterceptor());
  
    config.AddCommand<ProcessCommand>("process")
        .WithDescription("Process files");
});
  
return await app.RunAsync(args);

Common Use Cases

  • Logging: Configure log scopes in Intercept, flush logs in InterceptResult
  • Timing: Start a stopwatch before, report duration after
  • Authentication: Validate credentials before any command runs
  • Resource management: Initialize connections before, clean up after
  • Exit code adjustment: Modify the result based on post-execution checks

The InterceptResult method receives the exit code by reference (ref int result), allowing you to modify it based on the command outcome.

See Also