初めに
EntityFrameworkCoreでは、nugetパッケージを追加すると、dotnet-cliコマンドでdotnet ef
コマンドが使用できるようになるという機能がある。
これが応用できれば、独自のソース生成ツールの使用等に使えると思うので、やり方を調べてみた。
大雑把な手順
- サブコマンドプロジェクトの作成
- サブコマンドプロジェクトのnugetパッケージ化
- 使用プロジェクトでサブコマンドプロジェクトのnugetパッケージ追加
以上でdotnetコマンドで使えるようになる
サブコマンドプロジェクトの作成
実はサブコマンドの実体は、単なるdotnet coreのコンソールアプリケーションになるので、プログラム自体は通常のコンソールアプリケーションとほとんど変わりはない。
ただし、出力するDLLあるいはEXE名は、dotnet-[サブコマンド名].[dll又はexe]
という形式にしなければならないというルールがある。
ここでnugetのパッケージ名をそのままdotnet-[サブコマンド名]
としても問題はないが、nugetパッケージ名に別名(MyApp.MySubCommand
等)を使用したい場合、以下のようにcsprojのProject/PropertyGroup/AssemblyName
に拡張子なしの名前を指定すれば、出力アセンブリ名を変更できる。
<Project Sdk="Microsoft.Net.Sdk">
<PropertyGroup>
<AssemblyName>dotnet-[サブコマンド名]</AssemblyName>
</Property>
</Project>
使用フレームワークについて
サブコマンドプロジェクトで使用するフレームワークについては、dotnetコマンドで解釈できる形式であればいいので、
サブコマンドを使用するプロジェクトと必ずしも一致させる必要はない。
例えば、使用する側のフレームワークはnet452で、サブコマンドプロジェクトのフレームワークをnetcoreapp1.0にしても問題はない。
ただし、プロジェクトのアセンブリを読み込むタイプのコマンド等は、使用フレームワークを合わせる必要があるかもしれない。
サブコマンドプロジェクトのnugetパッケージの作成
他のプロジェクトでサブコマンドとして使用する場合、nugetパッケージにして、そのnugetパッケージを読み込ませる必要があるため、nupkgファイルを作成する必要がある。これは、サブプロジェクト上でdotnet pack
を実行すればOK。具体的な使い方は以下リンク。
dotnet packコマンドについて
dotnet pack
コマンドを実行すると、[project.jsonがあるディレクトリ]/bin/[コンフィギュレーション]/[パッケージ名].[バージョン].nupkg
というパスにパッケージが出来上がる。
プロジェクト上でサブコマンドを使用するための準備
作成したサブコマンドを使用するには、前述の手順で作成したnupkgをproject.json内の"tools"セクションに、下記例のように記述する必要がある。
<Project Sdk="Microsoft.Net.Sdk">
<ItemGroup>
<DotNetCliToolReference Include="[パッケージ名]" Version="[パッケージバージョン]"/>
</ItemGroup>
</Project>
グローバルリポジトリに追加されたnupkgを参照する場合は、そのままでも使用可能だが、例えばローカルパッケージ等を参照したい場合は、project.jsonと同ディレクトリにNuGet.configファイルを作成し、packageSourcesにディレクトリを追加する必要がある。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="[任意のキー名]" value="[nupkgがあるディレクトリへのパス(csprojからの相対でも可)]"/>
</packageSources>
</configuration>
以上の準備をした後、dotnet restore
コマンドを実行すれば、参照を追加したプロジェクトで、dotnet-cliのサブコマンドが利用可能な状態になる。
制限
nugetパッケージとしてDotNetCliToolReference
要素で指定する必要があるため、PackageReference
やProjectReference
ではできない。
参考URL等
- 公式ドキュメント
-
Microsoft.EntityFrameworkCore.Tools
- EntityFramework Coreで使用されている
dotnet ef
コマンドの本体。プロジェクト参照等もしているので、自分で作る際に参考になると思う
- EntityFramework Coreで使用されている
- 今回検証のために作成したソース