Dela via


Så här konfigurerar du beroendeinmatning i System.CommandLine

Viktigt!

System.CommandLine är för närvarande i förhandsversion och den här dokumentationen är för version 2.0 beta 4. Viss information gäller förhandsversionsprodukt som kan ändras avsevärt innan den släpps. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, avseende informationen som visas här.

Använd en anpassad bindemedel för att mata in anpassade typer i en kommandohanterare.

Vi rekommenderar hanteringsspecifik beroendeinmatning (DI) av följande skäl:

  • Kommandoradsappar är ofta kortvariga processer, där startkostnaden kan ha en märkbar inverkan på prestandan. Det är särskilt viktigt att optimera prestanda när tabbavslut måste beräknas. Kommandoradsappar skiljer sig från webb- och GUI-appar, som tenderar att vara relativt långvariga processer. Onödig starttid är inte lämplig för kortvariga processer.
  • När en kommandoradsapp som har flera underkommandon körs körs bara en av dessa underkommandon. Om en app konfigurerar beroenden för de underkommandon som inte körs försämras prestandan i onödan.

För att konfigurera DI skapar du en klass som härleds från BinderBase<T> var T är gränssnittet som du vill mata in en instans för. GetBoundValue Hämta och returnera den instans som du vill mata in i metodens åsidosättning. I följande exempel matas standardimplementeringen för loggning in för ILogger:

public class MyCustomBinder : BinderBase<ILogger>
{
    protected override ILogger GetBoundValue(
        BindingContext bindingContext) => GetLogger(bindingContext);

    ILogger GetLogger(BindingContext bindingContext)
    {
        using ILoggerFactory loggerFactory = LoggerFactory.Create(
            builder => builder.AddConsole());
        ILogger logger = loggerFactory.CreateLogger("LoggerCategory");
        return logger;
    }
}

När du anropar SetHandler metoden skickar du till lambda en instans av den inmatade klassen och skickar en instans av din pärmklass i listan över tjänster:

rootCommand.SetHandler(async (fileOptionValue, logger) =>
    {
        await DoRootCommand(fileOptionValue!, logger);
    },
    fileOption, new MyCustomBinder());

Följande kod är ett komplett program som innehåller föregående exempel:

using System.CommandLine;
using System.CommandLine.Binding;
using Microsoft.Extensions.Logging;

class Program
{
    static async Task Main(string[] args)
    {
        var fileOption = new Option<FileInfo?>(
              name: "--file",
              description: "An option whose argument is parsed as a FileInfo");

        var rootCommand = new RootCommand("Dependency Injection sample");
        rootCommand.Add(fileOption);

        rootCommand.SetHandler(async (fileOptionValue, logger) =>
            {
                await DoRootCommand(fileOptionValue!, logger);
            },
            fileOption, new MyCustomBinder());

        await rootCommand.InvokeAsync("--file scl.runtimeconfig.json");
    }

    public static async Task DoRootCommand(FileInfo aFile, ILogger logger)
    {
        Console.WriteLine($"File = {aFile?.FullName}");
        logger.LogCritical("Test message");
        await Task.Delay(1000);
    }

    public class MyCustomBinder : BinderBase<ILogger>
    {
        protected override ILogger GetBoundValue(
            BindingContext bindingContext) => GetLogger(bindingContext);

        ILogger GetLogger(BindingContext bindingContext)
        {
            using ILoggerFactory loggerFactory = LoggerFactory.Create(
                builder => builder.AddConsole());
            ILogger logger = loggerFactory.CreateLogger("LoggerCategory");
            return logger;
        }
    }
}

Se även

System.CommandLine Översikt