Sdílet prostřednictvím


Konfigurace injektáže závislostí v System.CommandLine

Důležité

System.CommandLine je aktuálně ve verzi PREVIEW a tato dokumentace je určená pro verzi 2.0 beta 4. Některé informace se týkají předběžné verze produktu, který může být podstatně změněn před vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Pomocí vlastního pořadače vložte vlastní typy do obslužné rutiny příkazu.

Injektáž závislostí specifická pro obslužnou rutinu (DI) doporučujeme z následujících důvodů:

  • Aplikace příkazového řádku jsou často krátkodobé procesy, ve kterých mohou mít náklady na spuštění výrazný dopad na výkon. Optimalizace výkonu je obzvláště důležitá, když je potřeba počítat dokončení tabulátoru. Aplikace příkazového řádku jsou na rozdíl od aplikací webového a grafického uživatelského rozhraní, které mají tendenci být relativně dlouhou dobu trvání. Nepotřebná doba spuštění není vhodná pro krátkodobé procesy.
  • Když se spustí aplikace příkazového řádku s více dílčími příkazy, spustí se pouze jeden z těchto dílčích příkazů. Pokud aplikace konfiguruje závislosti pro dílčí příkazy, které se nespouštějí, zbytečně snižuje výkon.

Chcete-li nakonfigurovat DI, vytvořte třídu, která je odvozena od BinderBase<T> místa, kde T je rozhraní, pro které chcete vložit instanci. V přepsání GetBoundValue metody získejte a vraťte instanci, kterou chcete vložit. Následující příklad vloží výchozí implementaci protokolovacího nástroje pro 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;
    }
}

Při volání SetHandler metody předejte lambda instanci vložené třídy a předejte instanci vaší třídy binderu v seznamu služeb:

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

Následující kód je úplný program, který obsahuje předchozí příklady:

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

Viz také

System.CommandLine Přehled