NuGet の概要

最新の開発プラットフォームに欠かせないツールは、開発者が役に立つコードを作成、共有、および使用するために利用できるメカニズムです。 多くの場合、このようなコードは "パッケージ" にバンドルされています。このパッケージにはコンパイルされたコード (DLL) に加えて、このパッケージが使用されるプロジェクトで必要なその他のコンテンツが含まれています。

Microsoft がサポートする .NET (.NET Core を含む) のコード共有メカニズムである NuGet では、.NET 用のパッケージを作成、ホスト、使用する方法が定義されており、それらの各ロール用の ツールが提供されています

つまり、NuGet パッケージは、拡張子が .nupkg の 1 つの ZIP ファイルであり、コンパイル済みのコード (DLL)、そのコードに関連する他のファイル、パッケージのバージョン番号などの情報が記述されているマニフェストが含まれます。 開発者はコードを共有して、パッケージを作成し、それをパブリック ホストまたはプライベート ホストに公開します。 パッケージ利用者は、これらのパッケージを適切なホストから取得して、プロジェクトに追加した後、プロジェクトのコードでパッケージの機能を呼び出します。 その過程での細部はすべて NuGet 自体が処理します。

NuGet では、パブリック ホストの nuget.org に加えてプライベート ホストもサポートされるので、NuGet パッケージを使用して、組織またはワーク グループ専用のコードを共有できます。 また、自身のプロジェクト以外では使用されない専用のコードを格納するための便利な方法として、NuGet パッケージを使用することもできます。 要するに、NuGet パッケージは共有可能なコード単位ですが、特定の共有手段を必要とすることも、暗黙に指定することもありません。

作成者、ホスト、利用者の間のパッケージのフロー

パブリック ホストとしての役割の NuGet は、100,000 以上の個別パッケージの中央リポジトリを nuget.org で保持します。これらのパッケージを、毎日数百万人の .NET/.NET Core 開発者が使用しています。 また、NuGet を使うと、クラウド (Azure DevOps 上など)、プライベート ネットワーク、さらにはローカル ファイル システムで、プライベートにパッケージをホストすることもできます。 こうすることにより、これらのパッケージは、ホストにアクセスできる開発者のみが使用できるようになるので、パッケージを特定の利用者グループに対して利用可能にすることができます。 オプションの説明については、「Hosting your own NuGet feeds」(独自の NuGet フィードのホスト) をご覧ください。 さらに、構成オプションを使用して、指定されたコンピューターがアクセス可能なホストを厳密に制御して、パッケージが、nuget.org などのパブリック リポジトリではなく特定のソースから取得されるようにすることができます。

ホストは、それがどのような性質であっても、パッケージ 作成者 とパッケージ 利用者 の間の接続ポイントとして機能します。 作成者は、便利な NuGet パッケージを作成して、ホストに公開します。 利用者は、アクセスできるホストで役に立ち互換性のあるパッケージを検索し、ダウンロードしてプロジェクトに組み込みます。 プロジェクトにインストールされたパッケージの API は、プロジェクト コードの他の部分から利用できます。

パッケージ作成者、パッケージ ホスト、パッケージ利用者の間の関係

互換性を目的とするパッケージ

"互換性のある" パッケージとは、パッケージを利用するプロジェクトのターゲット フレームワークと互換性のある少なくとも 1 つの .NET Framework 用にビルドされたアセンブリが含まれていることを意味します。 開発者は、UWP コントロールと同様、1 つのフレームワークに固有のパッケージを作成することも、広範囲のターゲットをサポートすることもできます。 パッケージの互換性を最大化するには、開発者は、すべての .NET および .NET Core プロジェクトで利用可能な .NET Standard をターゲットにします。 この場合、単一のパッケージ (通常、単一のアセンブリを含む) が、パッケージを利用するすべてのプロジェクトに対して機能するので、作成者と利用者の両方にとって最も効率的な手段です。

一方、.NET Standard 以外の API を必要とするパッケージ開発者は、サポートするさまざまなターゲット フレームワーク用に個別のアセンブリを作成し、これらのすべてのアセンブリを同じパッケージに含めます (これは、「マルチターゲット」と呼ばれています)。 利用者がこのようなパッケージをインストールすると、NuGet では、プロジェクトで必要されるアセンブリのみが抽出されます。 これにより、最終的なアプリケーションやそのプロジェクトによって生成されるアセンブリでのパッケージのフットプリントが最小になります。 当然、作成者にとっては、マルチターゲット パッケージを保守する方が困難です。

注意

.NET Standard をターゲットにする方法は、さまざまなポータブル クラス ライブラリ (PCL) ターゲットを使用する以前の方法よりも優先されます。 このため、このドキュメントでは、.NET Standard 用のパッケージの作成に重点を置いて説明します。

NuGet のツール

ホストのサポートに加えて、NuGet では作成者と利用者の両方が使用できるさまざまなツールも提供されています。 特定のツールの取得方法については、「NuGet クライアント ツールのインストール」を参照してください。

ツール プラットフォーム 該当シナリオ 説明
dotnet CLI すべて 作成、利用 .NET Core と .NET Standard ライブラリ、および .NET Framework を対象とする SDK スタイルのプロジェクト (「SDK 属性」を参照) のための CLI ツール。 特定の NuGet CLI 機能を、.NET Core ツール チェーン内に直接提供します。 nuget.exe CLI と同様、dotnet CLI によって Visual Studio プロジェクトが操作されることはありません。
nuget.exe CLI すべて 作成、利用 .NET Framework ライブラリと、.NET Standard ライブラリを対象とする非 SDK スタイルのプロジェクトのための CLI ツール。 NuGet のすべての機能を提供します。パッケージ作成者のみに適用されるコマンド、利用者のみに適用されるもの、両方に適用されるものがあります。 たとえば、パッケージ作成者は nuget pack コマンドを使用して、さまざまなアセンブリと関連ファイルからパッケージを作成し、パッケージ利用者は nuget install を使用して、パッケージをプロジェクトフォルダーに格納します。また、nuget config は、NuGet の構成変数を設定するためにすべてのユーザーによって使用されます。 プラットフォームに依存しないツールである NuGet CLI は、Visual Studio プロジェクトと対話しません。
パッケージ マネージャー コンソール Windows の Visual Studio 利用 Visual Studio プロジェクトでパッケージをインストールして管理するための PowerShell コマンドを提供します。
パッケージ マネージャー UI Windows の Visual Studio 利用 Visual Studio プロジェクトでパッケージをインストールして管理するための使いやすい UI を提供します。
NuGet 管理 UI Visual Studio for Mac 利用 Visual Studio for Mac プロジェクトでパッケージをインストールして管理するための使いやすい UI を提供します。
MSBuild Windows 作成、利用 パッケージを作成する機能と、プロジェクトで使用されているパッケージを、MSBuild ツール チェーンを介して直接復元する機能を提供します。

このように、どの NuGet ツールを使用するかは、パッケージの作成、利用、公開のいずれを行うか、およびどのプラットフォームで作業しているかによって大きく異なります。 パッケージ作成者は、通常、他の NuGet パッケージの機能を基にして開発を行うので、利用者でもあります。 そして、これらのパッケージは、もちろん、他のパッケージにさらに依存している場合があります。

詳細については、「パッケージ作成ワークフロー」 および パッケージ利用のワークフロー」の記事を最初にお読みください。

依存関係の管理

他の開発者の作業を簡単に利用できることは、パッケージ管理システムの最も強力な機能の 1 つです。 したがって、NuGet の機能の多くは、プロジェクトに代わって、その依存関係ツリーつまり "グラフ" を管理することです。 簡単に言えば、開発者が関心を持つ必要があるのは、プロジェクト内で直接使っているパッケージだけです。 そのようなパッケージ自体のいずれかで他のパッケージ (それがさらに他のパッケージを利用している場合があります) が利用されている場合、下位の依存関係はすべて NuGet で処理されます。

次の図で示すプロジェクトは、5 つのパッケージに依存しており、それらがさらに他の複数のパッケージに依存しています。

.NET プロジェクトの NuGet 依存関係グラフの例

依存関係グラフの複数の箇所に出現しているパッケージがあることに注意してください。 たとえば、パッケージ B には 3 つの異なるコンシューマーがあり、各コンシューマーがそのパッケージの異なるバージョンを指定している可能性もあります (図には示されていません)。 特に広く使用されているパッケージの場合、これはよくあることです。 さいわいなことに、すべての利用者の要求を満たすパッケージ B のバージョンを正確に特定する困難な作業はすべて、NuGet によって実行されます。 その後、NuGet は、依存関係グラフの深さに関係なく、他のすべてのパッケージについても同じように処理します。

NuGet がこのサービスを実行する方法について詳しくは、依存関係の解決に関するページをご覧ください。

参照の追跡とパッケージの復元

プロジェクトは開発者のコンピューター、ソース管理リポジトリ、ビルド サーバーなどの間を簡単に移動するので、プロジェクトに直接バインドされた NuGet パッケージからバイナリ アセンブリを維持するのは極めて困難です。 プロジェクトの各コピーが必要以上に肥大化する (それにより、ソース管理リポジトリ内の領域を浪費する) だけでなく、 パッケージのバイナリを新しいバージョンに更新する処理も、プロジェクトのすべてのコピーについて行う必要があるため、非常に困難になります。

代わりに、NuGet は、最上位と下位の依存関係を含めて、プロジェクトが依存する、単純なパッケージの参照リストを保持します。 つまり、どこかのホストからプロジェクトにパッケージをインストールすると常に、NuGet によってパッケージの識別子とバージョン番号がこの参照リストに記録されます (もちろん、パッケージをアンインストールするとリストから削除されます)。その後、「パッケージの復元」で説明しているように、NuGet は、参照されているすべてのパッケージを復元する手段を提供します。

NuGet の参照リストはパッケージのインストール時に作成され、別の場所にパッケージを復元するために使うことができる

それ以降いつでも、NuGet は、参照リストのみを使って、パブリック ホストやプライベート ホストからすべてのパッケージを再インストール、—つまり 復元—できます。 ソース管理にプロジェクトをコミットするとき、またはプロジェクトを他のなんらかの方法で共有する場合は、参照リストを含めるだけで済み、パッケージのバイナリを含める必要はありません (「パッケージとソース管理」を参照してください)。

自動展開システムの一部としてプロジェクトのコピーを取得するビルド サーバーのような、プロジェクトを受け取るコンピューターは、必要なときに依存関係を復元するよう NuGet に要求するだけです。 Azure DevOps などのビルド システムでは、この目的のための "NuGet 復元" ステップが提供されています。 同様に、開発者は、プロジェクトのコピーを取得する場合 (リポジトリを複製するときと同じように)、nuget restore (NuGet CLI)、dotnet restore (dotnet CLI)、または Install-Package (パッケージ マネージャー コンソール) などのコマンドを呼び出して、すべての必要なパッケージを取得できます。 この部分については、Visual Studio では、プロジェクトを構築するときに自動的にパッケージを復元します (「ただし、「パッケージの復元」で説明されているように、自動復元が有効になっていることが条件です)。

その場合に開発者が関係する NuGet の主要な役割は明らかに、プロジェクトに代わってその参照リストを維持し、参照されているパッケージを効率的に復元 (および更新) する手段を提供することです。 このリストは、次の 2 つの パッケージ管理形式 のいずれかで保持されます。

  • PackageReference (または "プロジェクト ファイルでのパッケージ参照") | (NuGet 4.0 以降) プロジェクトの最上位の依存関係のリストがプロジェクト ファイル内に直接保持されるので、個別のファイルは必要ありません。 関連するファイル obj/project.assets.json は、プロジェクトがすべての下位レベルの依存関係と共に使用するパッケージの依存関係の全体グラフを管理するために、動的に作成されます。 PackageReference は常に、.NET Core プロジェクトで使用されます。

  • packages.config: (NuGet 1.0 以降) プロジェクト内のすべての依存関係のフラット リストを保持する XML ファイルです。インストールされている他のパッケージの依存関係も含みます。 インストールまたは復元されたパッケージは、packages フォルダーに保管されます。

指定されたプロジェクトでどのパッケージ管理形式が採用されるかは、プロジェクトの種類と、NuGet (および Visual Studio) の使用可能なバージョンによって異なります。 使用されている形式を確認するには、最初のパッケージをインストールした後で、プロジェクトのルートにある packages.config を調べるだけで済みます。 そのファイルが見つからない場合は、プロジェクト ファイルで直接 <PackageReference> 要素を調べます。

いくつかの選択肢がある場合は、PackageReference を使用することをお勧めします。 packages.config はレガシを目的として保持され、アクティブな開発からは除外されます。

ヒント

nuget install などのさまざまな nuget.exe CLI コマンドが、パッケージを参照リストに自動追加することはありません。 リストは、Visual Studio パッケージ マネージャー (UI またはコンソール) でパッケージをインストールしたとき、また、dotnet.exe CLI によって、更新されます。

NuGet の他の機能

これまで、NuGet の次の特性について説明しました。

  • NuGet は、中央リポジトリ nuget.org を提供し、プライベート ホスティングをサポートします。
  • NuGet は、開発者がパッケージの作成、公開、使用に必要なツールを提供します。
  • 最も重要な特性として、NuGet は、プロジェクトで使用されるパッケージの参照リストを保持し、そのリストからパッケージを復元および更新できます。

これらの処理を効率的に実行するため、NuGet はバックグラウンドでいくつかの最適化を行います。 注目すべき点は、NuGet ではパッケージ キャッシュとグローバル パッケージ フォルダーを管理して、インストールおよび再インストールを省略することです。 キャッシュは、コンピューターに既にインストールされているパッケージのダウンロードを回避します。 グローバル パッケージ フォルダーは、インストールされている同じパッケージを複数のプロジェクトで共有できるようにし、それによりコンピューター上の NuGet のフット プリント全体を減らします。 また、キャッシュおよびグローバル パッケージ フォルダーは、ビルド サーバーなどのように多数のパッケージを頻繁に復元する場合は非常に役立ちます。 これらのメカニズムの詳細については、「Managing the global packages and cache folders」 (グローバル パッケージおよびキャッシュ フォルダーを管理する) をご覧ください。

個々のプロジェクトでは、NuGet は依存関係グラフ全体を管理します。これにも、同じパッケージの異なるバージョンへの複数の参照の解決が含まれます。 プロジェクトが 1 つ以上のパッケージに依存関係を持ち、それらのパッケージ自体にも同じような依存関係があることは、ごく一般的なことです。 nuget.org の最も便利なユーティリティ パッケージのいくつかは、他の多くのパッケージで使用されています。 依存関係グラフ全体では、同じパッケージの異なるバージョンに対する 10 個の異なる参照が簡単にできてしまいます。 そのパッケージの複数のバージョンがアプリケーション自体に組み込まれるのを回避するために、NuGet は、すべての利用者が使用できる 1 つのバージョンを選別します (詳細については、「依存関係の解決」を参照してください)。

さらに、NuGet は、パッケージの構成方法 (ローカライズデバッグ シンボルを含みます) およびパッケージの参照方法 (バージョン参照プレリリース バージョンを含みます) に関するすべての仕様を保持しています。NuGet は、そのサービスとプログラムで連携する各種の API を提供し、Visual Studio 拡張機能およびプロジェクト テンプレートを作成する開発者用のサポートも提供します。

このドキュメントの目次を見るとわかるように、これらすべての機能に関するトピックと、最初の NuGet からのすべてのリリース ノートが提供されています。

他の NuGet ビデオは、Channel 9 および YouTube でご覧いただけます。

コメント、投稿、問題

最後に、このドキュメントに関するコメントや投稿をお寄せください。—各ページの上部にある [ご意見ご感想] および [編集] コマンドを選択するか、GitHub の ドキュメント リポジトリおよび ドキュメント問題リストにアクセスしてください。

また、さまざまな GitHub リポジトリから NuGet 自体への投稿も歓迎します。NuGet の問題については、https://github.com/NuGet/home/issues をご覧ください。

NuGet のエクスペリエンスをお楽しみください。