Bagikan melalui


Cara mengonfigurasi injeksi dependensi di System.CommandLine

Penting

System.CommandLine saat ini dalam PRATINJAU, dan dokumentasi ini untuk versi 2.0 beta 4. Beberapa informasi terkait produk prarilis yang dapat diubah secara signifikan sebelum dirilis. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Gunakan pengikat kustom untuk menyuntikkan jenis kustom ke dalam handler perintah.

Kami merekomendasikan injeksi ketergantungan khusus handler (DI) karena alasan berikut:

  • Aplikasi baris perintah sering kali merupakan proses yang berumur pendek, di mana biaya startup dapat berdampak nyata pada performa. Mengoptimalkan performa sangat penting ketika penyelesaian tab harus dihitung. Aplikasi baris perintah tidak seperti aplikasi Web dan GUI, yang cenderung merupakan proses yang relatif berumur panjang. Waktu startup yang tidak perlu tidak sesuai untuk proses yang berumur pendek.
  • Saat aplikasi baris perintah yang memiliki beberapa subperintah dijalankan, hanya salah satu subperintah tersebut yang akan dijalankan. Jika aplikasi mengonfigurasi dependensi untuk subperintah yang tidak berjalan, aplikasi tidak perlu menurunkan performa.

Untuk mengonfigurasi DI, buat kelas yang berasal dari BinderBase<T> di mana T adalah antarmuka yang ingin Anda masukkan instansnya. Dalam penggantian metode GetBoundValue, dapatkan dan kembalikan instans yang ingin Anda masukkan. Contoh berikut menyuntikkan implementasi pencatat default untuk 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;
    }
}

Saat memanggil metode SetHandler, teruskan ke lambda sebuah instans dari kelas yang disuntikkan dan berikan sebuah instans dari kelas binder Anda dalam daftar layanan:

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

Kode berikut adalah program lengkap yang berisi contoh sebelumnya:

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

Lihat juga

System.CommandLine ringkasan