Condividi tramite


Come configurare l'inserimento delle dipendenze in System.CommandLine

Importante

System.CommandLine è attualmente disponibile in ANTEPRIMA e questa documentazione è per la versione 2.0 beta 4. Alcune informazioni riguardano il prodotto in versione non definitiva che potrebbe essere modificato in modo sostanziale prima del rilascio. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Usare un binder personalizzato per inserire tipi personalizzati in un gestore comandi.

Si consiglia di usare l'inserimento delle dipendenze (DI) specifico del gestore per i motivi seguenti:

  • Le applicazioni da riga di comando sono spesso processi di breve durata, in cui i costi di avvio possono avere un impatto notevole sulle prestazioni. L'ottimizzazione delle prestazioni è particolarmente importante quando è necessario calcolare i completamenti delle schede. Le applicazioni da riga di comando sono diverse dalle applicazioni Web e GUI, che tendono a essere processi relativamente di lunga durata. Il tempo di avvio non necessario non è appropriato per i processi di breve durata.
  • Quando viene eseguita un'applicazione da riga di comando con più sottocomandi, verrà eseguito solo uno di tali sottocomandi. Se un'applicazione configura le dipendenze per i sottocomandi che non vengono eseguiti, le prestazioni vengono deteriorate inutilmente.

Per configurare la DI, creare una classe che deriva da BinderBase<T> dove T è l'interfaccia per la quale si vuole inserire un'istanza. Nell'override del metodo GetBoundValue ottenere e restituire l'istanza che si desidera inserire. L'esempio seguente inserisce l'implementazione del logger predefinito per 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;
    }
}

Quando si chiama il metodo SetHandler, passare all'espressione lambda un'istanza della classe inserita e passare un'istanza della classe Binder nell'elenco dei servizi:

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

Il codice seguente è un programma completo che contiene gli esempi precedenti:

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;
        }
    }
}

Vedi anche

Panoramica di System.CommandLine