다음을 통해 공유


System.CommandLine에서 미들웨어를 사용하는 방법

Important

System.CommandLine는 현재 미리 보기로 제공되며 이 설명서는 버전 2.0 베타 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로 전체 명령 처리 프로세스의 ‘루트’로 작동하는 단일 구조체입니다. 기능 측면에서 System.CommandLine에서 가장 강력한 구조 입니다. 미들웨어에는 두 가지 주요 용도가 있습니다.

  • 미들웨어가 사용자 지정 논리에 대한 종속성을 검색하기 위해 BindingContext, Parser, Console, HelpBuilder에 대한 액세스를 제공합니다.
  • 단락 방식으로 명령 처리를 종료하기 위해 InvocationResult 또는 ExitCode 속성을 설정할 수 있습니다. 예를 들어 이 방식으로 구현되는 --help 옵션이 있습니다.

필수 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 개요