はじめに
PcakgeReference
とProjectReference
を利用した下記のcsporj
があるとします。それぞれのプロジェクトをビルドする際に必要な.NET SDK
のバージョンは何か分かるでしょうか?
<!-- パターン1.csproj --> <TargetFramework>net8.0</TargetFramework> ... <ProjectReference Include="../Hoge/Hoge.csproj" />
<!-- パターン2.csproj --> <TargetFramework>net8.0</TargetFramework> ... <PackageReference Include="Hoge" Version="1.0.0" />
<!-- パターン1とパターン2から参照されているプロジェクト --> <TargetFrameworks>net8.0;net9.0</TargetFrameworks>
答えはProjectReference
の方はnet9
で、PackageReference
はnet8
です。またややこしいことに、ビルドするのにnet9
が必要でも実際にビルドされるtfm
はnet8
になります。
仕組みを理解すれば大したことではないのですが、割と初見殺しな気がするのでそこら辺について書き残しておきます。
概要
端的にまとめると
ProjectReference
は依存先プロジェクトもビルドするためより新しいバージョンの.NET SDKを要求するPackageReference
はビルド済みのライブラリを利用するため自身のプロジェクトをビルドできるSDKがあれば問題ない
という感じです。
PackageReference
PackageReference
は既に特定のTargetFramework
向けにビルド済みのアセンブリを利用します。(netstandard2.1
など互換性のある下位のアセンブリを利用することもある)
ですのでビルドに必要となる.NET SDKは、あくまでビルドを実行するプロジェクト自身のTargetFramework
に対応していればよいのです。
ProjectReference
ProjectReference
はNuGetパッケージとは異なり、ソースコードレベルでの依存となります。ProjectReference
を持つプロジェクトをビルドすると、依存先のプロジェクトも一緒にビルドされます。
つまりビルドに必要となる.NET SDKは、参照関係にあるすべてのプロジェクトのTargetFramework
をサポートするバージョンが要求されます。global.json
の影響がある可能性もあるかもですが、基本的に最新のものを入れておけばビルドできるはずです。
さいごに
私の場合ローカルでは色々なバージョンの.NET SDKが入っているので問題になることは少ないのですが、特にCI/CDで.NET SDKを用意する場合では気をつけたほうが良いでしょう。ProjectReference
の場合は依存先も調べないといけないので、結構分かりづらくご注意ください。