Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Concevoir une CLI moderne en .NET : retour d’expérience

2026年09月29日に「Dev.to」が公開したITニュース「Concevoir une CLI moderne en .NET : retour d’expérience」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

複雑なデータベース操作を効率化するため、使いにくいCLIを改善した経験談。コマンドを機能ごとに階層化し、自動ヘルプや設定管理機能を導入して使いやすさを向上させた。配布は.NET Toolで簡素化し、複数環境への対応も実現。これら設計ノウハウをまとめたテンプレートも提供しており、堅牢で快適なCLI開発の参考になる。

ITニュース解説

あるプロジェクトで、データベース(Azure Cosmos DB)の管理作業が大きな課題となった。具体的には、特定の条件でデータを削除したり、一時的にバックアップを取ったり、必要な情報を確認したりといった、繰り返し行う必要のある作業が多数発生した。これらの作業は、開発者が使うコンピューターだけでなく、画面のないサーバー(ヘッドレスサーバー)でも実行できる必要があった。

最初は、これらの作業をそれぞれ独立した小さなプログラム(スクリプト)として作成した。例えば、データを削除するプログラム、バックアップを取るプログラム、といった具合だ。しかし、それぞれのプログラムには共通する処理がたくさんあったため、プログラムの数が増えるにつれて、管理や修正が非常に難しくなっていった。

そこで、ばらばらになっていたこれらのプログラムを一つにまとめ、「TheSuperApp」と名付けた統合ツールを作成した。これにより、技術的な問題は解決されたかに見えたが、新たな問題が発生した。それは、このツールの使い方が非常に複雑になってしまったことだ。例えば、「TheSuperApp -operation save -saveoption file ...」のように、コマンドを実行する際に指定する引数(オプション)がとても長く、どれが必要な引数なのか、どの操作に使えるのかがすぐに分からなくなった。これでは、今後さらに新しい機能を追加するたびに、ますます使いにくいツールになってしまうことは明らかだった。

この問題を解決するため、私たちはCLI(コマンドラインインターフェース)の設計を根本から見直すことにした。一番大きな変更点は、CLIを「動詞」を中心とした階層構造にすることだった。これは、GitやDockerといった、多くの開発者が日常的に使うツールのコマンド体系に似ている。

具体的には、「save(保存)」「select(選択)」「delete(削除)」といった、実行したい「動作」を表す主要なコマンド(第一階層)を定義した。さらに、例えば「save」コマンドの下に「to-file(ファイルへ保存)」「to-litedb(LiteDBへ保存)」といった、より具体的な保存方法を指定するサブコマンドを用意した。そして、それぞれのコマンドやサブコマンドには、それら専用の引数を設定した。この階層的なアプローチにより、コマンドが読みやすく、何を実行したいのかが直感的に理解しやすくなった。また、コマンドの使い方を説明するヘルプメッセージも格段に分かりやすくなり、将来的に新しい機能を気軽に追加できるようになったため、ツールの拡張性も大きく向上した。

この新しいCLIを効率的に実装するため、「CommandLineUtils」というライブラリを採用した。このライブラリは、コマンドとサブコマンドの階層構造を簡単に定義できるだけでなく、コマンドの使い方を説明するヘルプメッセージを自動で生成してくれる機能も持っている。さらに、.NETの「Generic Host」(プログラムの共通的な基盤を提供する仕組み)ともスムーズに連携できるため、設定ファイルの読み込みなども容易に行える。CLIの構造や引数は、C#のクラスやプロパティに「属性」という特別な情報(例えば[Command("save")]や[Option]など)を付けるだけで定義できるため、コードも簡潔になった。

ツールが機能するようになったら、次にどうやって開発者や他のサーバーにこのツールを届けるかという課題が生じた。私たちは「.NET Tool」という配布形式を選択した。これは、.NETのソフトウェア部品をまとめて配布・管理する「NuGet」という仕組みの特別なパッケージ形式だ。

.NET Toolとして配布することには、すぐにいくつかのメリットがあった。まず、インターネット上の「NuGet.org」という公開サイトから簡単に配布でき、誰でも入手できる。次に、ツールをインストールするのに、管理者権限が不要なため、気軽に導入できる。また、コマンドラインから簡単にインストールや更新ができるので、画面のないサーバー(ヘッドレスサーバー)でも非常に便利だ。さらに、特定のバージョンを指定してインストールすることもできる。この形式で配布するには、プロジェクトの設定ファイルに数行の記述を追加するだけで、通常のコンソールアプリケーションを、グローバルにインストールしてどこからでも使えるツールに変換できる。

ツールを日常的に使っていく中で、毎回データベースの接続情報(接続文字列やデータベース名)をコマンドラインの引数として入力するのが面倒だと感じ始めた。そこで、Generic Hostが提供する「appsettings.json」のような設定ファイルを利用することにした。これにより、CLIツール自体が、これらの頻繁に使う情報をファイルに保存し、必要に応じて読み込んだり、変更したり、表示したりできるようにした。例えば、「TheSuperCli settings set --connection-string ...」のように一度設定を保存すれば、次回からは接続情報を入力する必要がなくなるため、コマンドがさらに短く、使いやすくなった。

さらに、プロジェクトが進むにつれて、開発環境、テスト環境、本番環境といった、複数の異なる環境でツールを使う必要が出てきた。それぞれの環境では、データベースの接続情報などが異なるため、一つの設定では対応しきれない。そこで、CLIに「環境」の概念を導入した。これは、「appsettings.dev.json」や「appsettings.prod.json」のように、環境ごとに異なる設定ファイルを管理する仕組みだ。

コマンドに「--env」という引数を追加することで、特定の環境の設定を操作できるようにした。例えば、「TheSuperCli settings set --database <<database>> --env prod」と実行すれば、本番環境のデータベース設定だけを変更できる。また、現在の設定を特定の環境として保存したり、別の環境の設定に切り替えたり、不要になった環境設定を削除したりするコマンドも追加した。これにより、複数の環境での運用が非常にスムーズになった。

これらの経験と成果を、今後のプロジェクトでも最大限に活用できるように、私たちはCLIのひな形となる「テンプレート」を作成し、NuGet.orgで公開した。このテンプレートを使えば、「dotnet new install lmondeil.cli.template」と「dotnet new lmondeil.cli --name <<cli name>>」という簡単なコマンドを実行するだけで、CommandLineUtilsや.NET Toolとしての配布、そして環境管理機能が最初から組み込まれた、きちんとした構造のCLIプロジェクトをすぐに開始できる。これにより、新しいCLIツールの開発効率が大幅に向上した。

この一連の経験から、CLIは単にプログラムを実行するための技術的な入り口というだけでなく、それ自体を「製品」として捉え、きちんと設計することの重要性を痛感した。適切に設計されたCLIは、その使い方を明確にし、ツールの信頼性を高め、そして何よりも、日々の作業において開発者や運用者に大きな快適さをもたらすことが分かった。

関連コンテンツ

関連IT用語