共用方式為


如何在 System.CommandLine 中使用中介軟體

重要

System.CommandLine 目前為預覽版,而此文件適用於版本 2.0 搶鮮版 (Beta) 4。 部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

本文說明如何在使用 System.CommandLine 程式庫建置的命令列應用程式中使用中介軟體。 使用中介軟體是大部分 System.CommandLine 使用者不需要考慮的進階主題。

中介軟體簡介

雖然每個命令都有一個處理常式 (System.CommandLine 會根據輸入路由傳送至該處理常式),但也會有一個機制可在叫用應用程式邏輯之前,先進行最少運算或改變輸入。 在剖析和叫用之間,有一連串您可以加以自訂的責任。 使用這項功能的一些 System.CommandLine 內建功能。 這是 --help--version 選項對處理常式進行簡短呼叫的方式。

管道中的每個呼叫都可以根據 ParseResult 採取動作並提早傳回,或選擇呼叫管道中的下一個項目。 在此階段期間,甚至可以取代 ParseResult。 鏈結中的最後一個呼叫是指定命令的處理常式。

新增至中介軟體管道

您可以藉由呼叫 CommandLineBuilderExtensions.AddMiddleware,將呼叫新增至此管道。 以下是啟用自訂指示詞的程式碼範例。 建立名為 rootCommand 的根命令之後,程式碼會如往常一樣新增選項、引數和處理常式。 接著會新增中介軟體:

var commandLineBuilder = new CommandLineBuilder(rootCommand);

commandLineBuilder.AddMiddleware(async (context, next) =>
{
    if (context.ParseResult.Directives.Contains("just-say-hi"))
    {
        context.Console.WriteLine("Hi!");
    }
    else
    {
        await next(context);
    }
});

commandLineBuilder.UseDefaults();
var parser = commandLineBuilder.Build();
await parser.InvokeAsync(args);

在上述程式碼中,如果剖析結果中找到指示詞 [just-say-hi],中介軟體會寫出 "Hi!"。 發生這種情況時,不會叫用命令的一般處理常式。 因為中介軟體不會呼叫 next 委派,所以不會叫用它。

在此範例中,contextInvocationContext,這是一種 singleton 結構,可作為整個命令處理程序的「根」。 這是 System.CommandLine 中功能最強大的結構。 它在中介軟體中有兩個主要用途:

以下是完整的程式,包括必要的 using 指示詞。

using System.CommandLine;
using System.CommandLine.Builder;
using System.CommandLine.Parsing;

class Program
{
    static async Task Main(string[] args)
    {
        var delayOption = new Option<int>("--delay");
        var messageOption = new Option<string>("--message");

        var rootCommand = new RootCommand("Middleware example");
        rootCommand.Add(delayOption);
        rootCommand.Add(messageOption);

        rootCommand.SetHandler((delayOptionValue, messageOptionValue) =>
            {
                DoRootCommand(delayOptionValue, messageOptionValue);
            },
            delayOption, messageOption);

        var commandLineBuilder = new CommandLineBuilder(rootCommand);

        commandLineBuilder.AddMiddleware(async (context, next) =>
        {
            if (context.ParseResult.Directives.Contains("just-say-hi"))
            {
                context.Console.WriteLine("Hi!");
            }
            else
            {
                await next(context);
            }
        });

        commandLineBuilder.UseDefaults();
        var parser = commandLineBuilder.Build();
        await parser.InvokeAsync(args);
    }

    public static void DoRootCommand(int delay, string message)
    {
        Console.WriteLine($"--delay = {delay}");
        Console.WriteLine($"--message = {message}");
    }
}

以下是上述程式碼的範例命令列和產生的輸出:

myapp [just-say-hi] --delay 42 --message "Hello world!"
Hi!

另請參閱

System.CommandLine 概觀