rksoftware

Visual Studio とか C# とかが好きです

コマンドライン引数を雑に扱う (4)

以前にコマンドライン引数を雑に扱う記事を書きました。

コンソールアプリ、ちょっとした処理を行う際に雑に作ってしまうのが結構いいのですが、何気にコマンドライン引数の解釈コードが面倒です。 それはもう、あらゆる要素をソースコードに書き込んで毎回ソースコード上の値を書き換えてビルドして使うほどに。

というわけで、引数を扱うコードを雑に書いてきたのですが、いつまでもいろいろ不完全だったりコードも雑すぎたので今後いじっていきやすいように NuGet パッケージ化してしまいました。

■ NuGet パッケージ

dotnet add package Rksoftware.ArgumentsBuilder

■ 引数レコード

解釈した引数の値を格納する record を用意します。

using Rksoftware.ArgumentsBuilder.Attributes;

record struct Arguments([Parameter] string? Aparam, [Parameter] string? Bparam, string? A, string? B, string? C, bool D, bool E) { }

Parameter という属性が付いている引数に、コマンドライン引数の何もない普通の引数が入ってきます。たとえば

<command> 1 2

として実行すると、引数 Aparam の値が 1 に、Bparam の値が 2 になります。

Parameter という属性が付いていない string? 型の引数は - や / で始まるオプション指定の値が入ってきます。たとえば

<command> -a 1  /b 2

として実行すると、引数 A の値が 1 に、B の値が 2 になります。

Parameter という属性が付いていない string? 型の引数は - や / で始まるオプション指定があった場合、true が入ってきます。たとえば

<command> -d /e

として実行すると、引数 D の値が true に、E の値が true になります。

■ 使用コード

引数レコード

using Rksoftware.ArgumentsBuilder.Attributes;

record struct Arguments([Parameter] string? Aparam, [Parameter] string? Bparam, string? A, string? B, string? C, bool D, bool E) { }

実行する処理を書くクラス

interface IService { }

class Service : IService
{
    public string Run(Arguments arguments) => arguments.ToString();
}

メインのプログラムクラス

ApplicationRun という拡張メソッドで、DI でとってくるインタフェースと引数レコードの型および引数を指定するだけで OK。
この例では ApplicationRun の中で IService インタフェースの実行クラスの中から Arguments 型の引数をもつメソッドを探して実行してくれます。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Rksoftware.ArgumentsBuilder.Hosts;

using IHost host = Host.CreateDefaultBuilder(args).ConfigureServices((_, services) => services.AddSingleton<IService, Service>()).Build();
var result = host.ApplicationRun<IService, Arguments>(args);

Console.WriteLine((string?)result);

簡単ですね。