.NET Standard NuGet パッケージが多くの依存関係をトリガーするのはなぜですか? 質問する

.NET Standard NuGet パッケージが多くの依存関係をトリガーするのはなぜですか? 質問する

私は.NET 標準プロジェクトNuGetです。プロジェクトが進行中で、NuGet.orgにアップロードしました私のプロジェクトは.NET Standard 1.3をターゲットにしており、サポートすべき.NET Framework 4.6 および .NET Core 1.0。

しかし、プロジェクトを(NuGet経由で)新しい.NET Framework 4.6プロジェクトに追加しようとすると、依存関係が解決され、47パッケージです。これらはすべてシステム ライブラリであり、Microsoft.NETCore.Platforms または NETStandard.Library 1.6.1 のいずれかに依存しているようです。(完全な PM 出力の要点。

私のプロジェクトでは、using少数のライブラリのみをインポート ( ) していますが、そのいずれも手動で追加したものではありません。つまり、それらはすべて .NET Standard に付属しているライブラリです。これらのライブラリは次のとおりです。

  1. システム
  2. システム.テキスト
  3. システム.リフレクション
  4. システム.Linq
  5. System.Collections.Generic;

実は、.NET Framework と .NET Core アプリケーション間でシームレスに動作するようにしたかったので、プロジェクトを .NET Standard 対象にすることに決めました。Standard の目的は、最低限の互換性レベルを設定することだと考えていました。さらに言えば、System.Console などのライブラリは Core または Framework のいずれかで自動的に使用可能になると (おそらく誤って) 想定していたと思います。

同じソリューション内のフレームワークおよびコア プロジェクトの依存関係として Standard プロジェクトをテストしたときには、このようなことは何も気づかなかったので、これは NuGet の問題である可能性があると疑っています。

ここでは実際に何が起こっているのでしょうか? また、膨大な依存関係のリストなしで、.NET Standard ライブラリを NuGet で利用できるようにするにはどうすればよいですか?

NuGet パッケージの指定方法に問題があるのでしょうか? それとも、何かを根本的に誤解しているのでしょうか?

ベストアンサー1

何も間違ったことをしていません。これは想定内のことです。新しい .NET Framework プロジェクトに独自の DLL を追加するだけの場合は、ライブラリのターゲットを .NET Standard 2.0 に設定し、API とアセンブリの両方のバージョンをネイティブにサポートする .NET Framework バージョン (4.7.2 になる予定) を待つ必要があります (.NET Framework 4.7.1 はすべての API をサポートしていますが、一部のアセンブリのバージョン管理方法にバグがあったため、ツール (VS 2017 15.5+) で追加のアセンブリを追加して修正します)。

ここで表示されているのは、.NET Standard の構築方法と、サポートされているフレームワークのサポートの実装方法による副作用です。これは、対象とする .NET Standard のバージョンと、ライブラリ パッケージを参照するために使用されるツールによっても異なります。

.NET Standard < 2.0 では、NETStandard.Libraryメタパッケージを参照し、メタパッケージは追加の ( System.*) パッケージを参照します。これらのパッケージには、API のセットとアセンブリ名 + バージョンである ".NET Standard Contract" を構成する参照アセンブリが含まれています。

.NET Standard 1.0-1.6 用に作成した NuGet パッケージがアプリケーションによって参照されると、これらの個々のパッケージは参照アセンブリではなく、アプリケーションが対象とするフレームワークの実装アセンブリを取得します。

.NET Core の場合、これらは既にランタイムの一部となっているアセンブリと一致するため、DLL ファイルはビルドされたアプリケーションの隣には配置されません。ただし、.NET Core 1.1 (NETStandard.Libraryバージョン 1.6.1) 用の新しいパッケージ セットがリリースされたときに、この状況は変わりました。その結果、.NET Core 1.0 用にビルドされたアプリケーションは、.NET Core 1.1 に含まれるはずの新しい実装アセンブリを取得することになりました (幸い、1.1 はその後「長期サポート」バージョンになりました。これにより、どのアセンブリが LTS の約束の一部であるかという議論が巻き起こったためです)。

.NET Framework では、これらのライブラリ ( などの例外はいくつかありますSystem.Net.Http) はあまり機能せず、システム アセンブリに転送するだけです。たとえば、「コントラクト」はアセンブリSystem.Objectで定義されている を定義しますSystem.Runtime.dll。そのため、System.Runtime.dll.NET Framework アプリケーションで最終的に作成されるファイルには、System.Runtime.dll.NET Framework の への型転送を含む が含まれますmscorlib.dll。.NET Core には、System.Runtime.dllそのプラットフォームに対して異なる処理を実行する が既に含まれています。このメカニズムにより、これらの型転送と追加の実装によって、両方の実装で動作する同じ「コントラクト」(型 + アセンブリ + アセンブリ バージョン) が保証されるため、単一の DLL ファイルを両方のプラットフォームで動作させることができます。

.NET Standard 2.0 は、必要なパッケージと DLL の数を減らし、NETStandard.Library新しい .NET Core バージョンがリリースされるたびに更新する必要がなくなることを目指しました。

したがって、.NET Standard 2.0 および .NET Core 2.0 の場合、NETStandard.Libraryパッケージはコードをコンパイルするための参照アセンブリのみをプロジェクトに持ち込みますが、結果として得られる NuGet パッケージはこのパッケージに依存しなくなります。そのため、.NET Standard 2.0 を対象とするライブラリを作成して公開すると、NuGet の依存関係はなくなります (追加の依存関係を追加しない限り)。

.NET Standard ライブラリを使用するときに取り込む「サポート ライブラリ」のロジックは、ビルド中に使用されるツールに移動されました。そのため、netstandard.dll.NET Framework プロジェクトに への参照を含むライブラリが追加されると、ツールは、使用されている .NET Framework のバージョンに基づいて必要なサポート DLL を追加します。.NET Framework 4.6.1 は、これらの種類の DLL ファイルを通じて、遡及的に .NET Standard 2.0 (以前は 1.4) と互換性を持つようになったため、これは .NET Standard 2.0 だけでなく .NET Standard 1.5+ でも実行されました。同じツールにより、NuGet パッケージが何らかの方法でこのようなアプリケーション プロジェクトに取り込まれた場合でも、NuGet 経由で取り込まれた .NET Standard 実装ライブラリはビルドから削除されます。そのため、.NET Core 1.0 がリリースされたときにビルドされた .NET Standard 1.0 NuGet パッケージを参照すると、そのすべての NuGet 依存関係が削除され、代わりにビルド ツールに同梱されているサポート ライブラリが取得されます。

アイデアとしては、.NET Framework 4.7.1 には必要なアセンブリがすべて「受信トレイ」に含まれているためnetstandard.dllSystem.Runtime.dllなどが .NET Framework の一部となり、.NET Standard 1.0-2.0 DLL ファイルが「そのまま機能」するというものでしたが、問題はこれらの「受信トレイ」の dll ファイルのバージョン番号が一部のアセンブリに対して低すぎるため、ライブラリの読み込みに失敗するというものでした。この問題は、ツールを再度変更して、より高いバージョン番号の DLL ファイルをサポート ライブラリとして含め、それを「受信トレイ」の .NET Framework アセンブリに転送することで修正されました。この問題は、.NET Framework 4.7.2 で修正される予定です。

おすすめ記事