.NET Framework の NuGet パッケージに依存関係が設定されない件に対処する（NU5218警告）

## このドキュメントの内容

プロジェクトのフレームワークが .NET Framework である場合、VisualStudio には NuGet パッケージを作成するための発行機能がありません。コマンドラインなどでパッケージを作成する必要があります。フレームワークのバージョンや参照しているパッケージなどの依存関係をパッケージに設定することができずに試行錯誤しました。その内容を紹介します。

## 先に結論

.NET Framework のパッケージを作成する場合、以下のようにするのがよさそうです。

* 新しいバージョンの NuGet コマンドラインツールを使用する。
  * 6.4.0 以降がリリースされた場合には別途確認する必要があると思われます。
* nspec ファイルに依存関係を明記する。
* 発行対象プロジェクトのパッケージ管理方式は PackageReference にする。直接参照したパッケージのみを nspec に記述するだけでよくなります。

## 依存関係を設定できるようになるまでにやったこと

### 発行対象のプロジェクト

* プロジェクトテンプレート「Windowsフォームコントロールライブラリ(.NET Framework)」で作成しました。.NET Framework のバージョンは 4.7.2 です。
* NuGet パッケージの管理方法を PackageReference に変更しました。
* Microsoft.Extensions.Hosting 7.0.0 を NuGet でインストールしました。
![sampleLibrary.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280969/e486137c-7f19-7be3-2ef0-1f351c8174dc.png)

 
### specファイルを作成する

*.csproj ファイルが格納されているディレクトリでコマンドプロンプトを開いて、spec コマンドを実行します。そのディレクトリに {プロジェクトファイル名}.spec ファイルが生成されます。

```console:NuGet5.6.1でspec
E:\SampleWinFormsLibrary1>nuget spec
'SampleWinFormsLibrary1.nuspec' が正常に作成されました。
```

```xml:NuGet5.6.1で生成されたspecファイル
<?xml version="1.0" encoding="utf-8"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">MIT</license>
    <projectUrl>http://project_url_here_or_delete_this_line/</projectUrl>
    <iconUrl>http://icon_url_here_or_delete_this_line/</iconUrl>
    <description>$description$</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2022</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>
</package>
```

この状態で pack を実行してみます。nupkg ファイルは生成されますが、いくつかの警告が検出されます。

```console:NuGet5.6.1でpack
E:\SampleWinFormsLibrary1>nuget pack -properties configuration=release
'SampleWinFormsLibrary1.csproj' からパッケージをビルドしています。
MSBuild auto-detection: using msbuild version '17.2.1.25201' from 'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\bin'.
'E:\SampleWinFormsLibrary1\bin\Release' のファイルをパックしています。
メタデータに 'SampleWinFormsLibrary1.nuspec' を使用しています。
Successfully created package 'E:\SampleWinFormsLibrary1\SampleWinFormsLibrary1.1.0.0.nupkg'.
警告: NU5102: The value "http://project_url_here_or_delete_this_line/" for projectUrl is a sample value and should be removed. Replace it with an appropriate value or remove it and rebuild your package.
警告: NU5102: The value "http://icon_url_here_or_delete_this_line/" for iconUrl is a sample value and should be removed. Replace it with an appropriate value or remove it and rebuild your package.
警告: NU5102: The value "Tag1 Tag2" for tags is a sample value and should be removed. Replace it with an appropriate value or remove it and rebuild your package.
警告: NU5102: The value "Summary of changes made in this release of the package." for releaseNotes is a sample value and should be removed. Replace it with an appropriate value or remove it and rebuild your package.
警告: NU5128: Some target frameworks declared in the dependencies group of the nuspec and the lib/ref folder do not have exact matches in the other location. Consult the list of actions below:
- Add a dependency group for .NETFramework4.7.2 to the nuspec
警告: NU5048: The 'PackageIconUrl'/'iconUrl' element is deprecated. Consider using the 'PackageIcon'/'icon' element instead. Learn more at https://aka.ms/deprecateIconUrl
```

|ID|説明|
|:--|:--|
|NU5102|既定値のままで残していると警告扱いになります。正しく値を設定するか、不要であれば削除します。|
|NU5128|依存するフレームワークが指定されていないという警告です。このドキュメントの主題はこの警告の解決方法です。|
|NU5048|`iconUrl`が廃止されたことによる警告です。|

### 警告を解決する

次のように spec ファイルを変更しました。

* projectUrl の値を設定しました。
* iconUrl タグをコメントアウトしました。
* releaseNotes の値を設定しました。
* tags の値を設定しました。
* dependencies タグを追加しました。
  * 発行対象のアプリケーションのフレームワークに合わせた group を追加しました。

```xml:変更後のspecファイル
<?xml version="1.0" encoding="utf-8"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">MIT</license>
    <projectUrl>https://github.com/mxProject/</projectUrl>
    <!-- <iconUrl>http://icon_url_here_or_delete_this_line/</iconUrl> -->
    <description>$description$</description>
    <releaseNotes>Initial release.</releaseNotes>
    <copyright>Copyright 2022 mxProject</copyright>
    <tags>Sample WindowsForm</tags>
    <dependencies>
      <group targetFramework="net472" />
    </dependencies>
  </metadata>
</package>
```

再度 pack を実行しました。NU5128 は解決しませんでした。

```console:NuGet5.6.1でpack
E:\SampleWinFormsLibrary1>nuget pack -properties configuration=release
'SampleWinFormsLibrary1.csproj' からパッケージをビルドしています。
MSBuild auto-detection: using msbuild version '17.2.1.25201' from 'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\bin'.
'E:\SampleWinFormsLibrary1\bin\Release' のファイルをパックしています。
メタデータに 'SampleWinFormsLibrary1.nuspec' を使用しています。
Successfully created package 'E:\SampleWinFormsLibrary1\SampleWinFormsLibrary1.1.0.0.nupkg'.
警告: NU5128: Some target frameworks declared in the dependencies group of the nuspec and the lib/ref folder do not have exact matches in the other location. Consult the list of actions below:
- Add a dependency group for .NETFramework4.7.2 to the nuspec
```

NuGetのパッケージ管理ページにも依存関係は表示されません。
![nuget561.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280969/266bbe85-43b0-d1a5-ae46-c1e6d642222e.png)

### NuGetのバージョンを変えてみる

NU5128 は Nuget5.3+ の不具合ではないかという話があります。

https://github.com/NuGet/Home/issues/8713

#### NuGet 5.2.1

5.2.1 を使って pack してみたところ、NU5128 は検出されませんでした。

```console:NuGet5.2.1でpack
E:\SampleWinFormsLibrary1>nuget pack -properties configuration=release
'SampleWinFormsLibrary1.csproj' からパッケージをビルドしています。
MSBuild auto-detection: using msbuild version '17.2.1.25201' from 'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\bin'.
'E:\SampleWinFormsLibrary1\bin\Release' のファイルをパックしています。
メタデータに 'SampleWinFormsLibrary1.nuspec' を使用しています。
Successfully created package 'E:\SampleWinFormsLibrary1\SampleWinFormsLibrary1.1.0.0.nupkg'.
```

しかしながら、パッケージ管理ページで見てみると依存関係は表示されませんでした。"NuGet5.2.1" は、前のパッケージがキャッシュされていないことを示すために pack を実行する前にタグに付加した文字列です。
![nuget521.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280969/eb77a2ae-22ba-a005-fa9b-3aba2115d177.png)

#### NuGet 6.4.0

2022/12/18 時点の推奨最新バージョンである 6.4.0 を使って pack してみたところ、同じく NU5128 は検出されませんでした。

```console:Nuget6.4.0でpack
E:\SampleWinFormsLibrary1>nuget pack -properties configuration=release
'SampleWinFormsLibrary1.csproj' からパッケージをビルドしようとしています。
MSBuild 自動検出: 'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\bin' から MSBuild バージョン '17.2.1.25201' を使用します。
'E:\SampleWinFormsLibrary1\bin\Release' からのファイルをパッキングしています。
メタデータに対して 'SampleWinFormsLibrary1.nuspec' を使用しています。
Successfully created package 'E:\SampleWinFormsLibrary1\SampleWinFormsLibrary1.1.0.0.nupkg'.
```

依存関係にフレームワークのバージョンが表示されましたが、依存しているパッケージは表示されませんでした。
![nuget641.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280969/00cb00f1-95da-a1e1-fcd2-7e558b6a5886.png)
このパッケージをインストールしても Microsoft.Extensions.Hosting は参照エラーになります。
![sampleCode.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280969/be8f3234-ca1a-a74d-1212-360bbdb98ad9.png)


### 依存パッケージを明記する

net472 グループに依存するパッケージを記述しました。

```xml:変更したspecファイル
<?xml version="1.0" encoding="utf-8"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">MIT</license>
    <projectUrl>https://github.com/mxProject/</projectUrl>
    <!-- <iconUrl>http://icon_url_here_or_delete_this_line/</iconUrl> -->
    <description>$description$</description>
    <releaseNotes>Initial release.</releaseNotes>
    <copyright>Copyright 2022 mxProject</copyright>
    <tags>Sample WindowsForm NuGet6.4.0</tags>
    <dependencies>
      <group targetFramework="net472">
        <dependency id="Microsoft.Extensions.Hosting" version="7.0.0" />
      </group>
    </dependencies>
  </metadata>
</package>
```

依存関係にパッケージが表示されました！
![nuget641.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280969/dfb09960-5d22-81b7-68ec-737c130b31ae.png)
NuGet でインストールするとき、Microsoft.Extensions.Hosting だけでなく、Microsoft.Extensions.Hosting が依存するパッケージも追跡されています。
![install.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280969/21ca9b07-1aad-32fd-6a5d-5ce32d7a8167.png)
Microsoft.Extensions.Hosting や Microsoft.Extensions.Logging で提供されている型が参照できています。
![sampleCode.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280969/73ac9e63-af5b-683e-a245-d278eda0adca.png)