多くのライブラリは、特定のバージョンの .NET Framework を対象としています。 たとえば、UWP に固有のライブラリのバージョンと、.NET Framework 4.6 の機能を利用する別のバージョンがあるとします。 これに対応するために、NuGet では、同じライブラリの複数のバージョンを 1 つのパッケージに配置できます。
この記事では、パッケージまたはアセンブリのビルド方法に関係なく、NuGet パッケージのレイアウトについて説明します (つまり、複数の非 SDK スタイル の .csproj ファイルとカスタム .nuspec ファイルを使用するか、単一のマルチターゲット SDK スタイル の .csproj を使用するかに関係なく、レイアウトは同じです)。 SDK スタイルのプロジェクトの場合、NuGet パック ターゲット はパッケージのレイアウト方法を認識し、アセンブリを適切な lib フォルダーに配置し、各ターゲット フレームワーク (TFM) の依存関係グループを作成する自動化を行います。 詳細な手順については、 プロジェクト ファイルで複数の .NET Framework バージョンをサポートするを参照してください。
パッケージの作成で説明されている規則ベースの作業ディレクトリ メソッドを使用する場合は、この記事の説明に従って パッケージを手動でレイアウトする必要があります。 SDK スタイルのプロジェクトの場合は、自動化された方法をお勧めしますが、この記事の説明に従ってパッケージを手動でレイアウトすることもできます。
フレームワーク バージョンのフォルダー構造
ライブラリの 1 つのバージョンのみを含むパッケージをビルドする場合、または複数のフレームワークを対象とする場合は、常に、次の規則で異なる大文字と小文字を区別するフレームワーク名を使用して、 lib の下にサブフォルダーを作成します。
lib\{framework name}[{version}]
サポートされている名前の完全な一覧については、 ターゲット フレームワークのリファレンスを参照してください。
フレームワークに固有ではなく、ルート lib フォルダーに直接配置するライブラリのバージョンを用意しないでください。 (この機能は、 packages.configでのみサポートされていました)。 これにより、ライブラリがターゲット フレームワークと互換性を持ち、任意の場所にインストールできるようになるため、予期しないランタイム エラーが発生する可能性があります。 ルート フォルダー ( lib\abc.dll など) またはサブフォルダー ( lib\abc\abc.dll など) へのアセンブリの追加は非推奨となり、PackagesReference 形式を使用する場合は無視されます。
たとえば、次のフォルダー構造では、フレームワーク固有の 4 つのバージョンのアセンブリがサポートされています。
\lib
\net46
\MyAssembly.dll
\net461
\MyAssembly.dll
\uap
\MyAssembly.dll
\netcore
\MyAssembly.dll
パッケージのビルド時にこれらのファイルをすべて簡単に含めるには、**の<files> セクションで再帰的な.nuspecワイルドカードを使用します。
<files>
<file src="lib\**" target="lib/{framework name}[{version}]" />
</files>
アーキテクチャ固有のフォルダー
アーキテクチャ固有のアセンブリ (つまり、ARM、x86、x64 を対象とする個別のアセンブリ) がある場合は、runtimes または {platform}-{architecture}\lib\{framework} という名前のサブフォルダー内の {platform}-{architecture}\native という名前のフォルダーに配置する必要があります。 たとえば、次のフォルダー構造は、Windows 10 と uap10.0 フレームワークを対象とするネイティブ DLL とマネージド DLL の両方に対応します。
\runtimes
\win10-arm
\native
\lib\uap10.0
\win10-x86
\native
\lib\uap10.0
\win10-x64
\native
\lib\uap10.0
これらのアセンブリは実行時にのみ使用できるため、対応するコンパイル時アセンブリを指定する場合は、AnyCPU フォルダーにアセンブリ/ref/{tfm}します。
NuGet は常にこれらのコンパイルアセットまたはランタイムアセットを 1 つのフォルダーから選択するので、 /ref から互換性のあるアセットがある場合、コンパイル時アセンブリを追加 /lib は無視されます。 同様に、 /runtimes から互換性のあるアセットがある場合、実行時にも /lib は無視されます。
マニフェストでこれらのファイルを参照する例については、「.nuspec」を参照してください。
また、「NuGet を使用した Windows ストア アプリ コンポーネントのパッキング」も参照してください。
プロジェクト内のアセンブリ バージョンとターゲット フレームワークの照合
NuGet は、複数のアセンブリ バージョンを持つパッケージをインストールすると、アセンブリのフレームワーク名とプロジェクトのターゲット フレームワークとの照合を試みます。
一致するものが見つからない場合、NuGet は、プロジェクトのターゲット フレームワーク以下の最上位バージョン (使用可能な場合) のアセンブリをコピーします。 互換性のあるアセンブリが見つからない場合、NuGet は適切なエラー メッセージを返します。
たとえば、パッケージ内の次のフォルダー構造を考えてみましょう。
\lib
\net45
\MyAssembly.dll
\net461
\MyAssembly.dll
.NET Framework 4.6 を対象とするプロジェクトにこのパッケージをインストールすると、NuGet はアセンブリを net45 フォルダーにインストールします。これは、4.6 以下の使用可能な最高バージョンであるためです。
一方、プロジェクトが .NET Framework 4.6.1 を対象とする場合、NuGet はアセンブリを net461 フォルダーにインストールします。
プロジェクトが .NET Framework 4.0 以前を対象とする場合、NuGet は互換性のあるアセンブリを見つからないことを示す適切なエラー メッセージをスローします。
フレームワーク バージョン別にアセンブリをグループ化する
NuGet は、パッケージ内の 1 つのライブラリ フォルダーからのみアセンブリをコピーします。 たとえば、パッケージに次のフォルダー構造があるとします。
\lib
\net40
\MyAssembly.dll (v1.0)
\MyAssembly.Core.dll (v1.0)
\net45
\MyAssembly.dll (v2.0)
.NET Framework 4.5 を対象とするプロジェクトにパッケージがインストールされている場合、インストールされているアセンブリは MyAssembly.dll (v2.0) だけです。
MyAssembly.Core.dll (v1.0) は、 net45 フォルダーに一覧表示されていないため、インストールされていません。
MyAssembly.Core.dllがバージョン 2.0 のMyAssembly.dllにマージされた可能性があるため、NuGet はこのように動作します。
.NET Framework 4.5 MyAssembly.Core.dll インストールする場合は、 net45 フォルダーにコピーを配置します。
フレームワーク プロファイルによるアセンブリのグループ化
NuGet では、フォルダーの末尾にダッシュとプロファイル名を追加することで、特定のフレームワーク プロファイルをターゲットにすることもできます。
lib{framework name}-{profile}
サポートされているプロファイルは次のとおりです。
-
client: クライアント プロファイル -
full: 完全なプロファイル -
wp:Windows Phone -
cf: コンパクトフレームワーク
依存関係の宣言 (詳細)
プロジェクト ファイルをパックすると、NuGet はプロジェクトから依存関係を自動的に生成しようとします。 . nuspec ファイルを使用して依存関係を宣言する方法に関するこのセクションの情報は、通常、高度なシナリオでのみ必要です。
(バージョン 2.0 以降)要素内の<group>要素を使用して、ターゲット プロジェクトのターゲット フレームワークに対応する <dependencies> でパッケージの依存関係を宣言できます。 詳細については、 dependencies 要素を参照してください。
各グループには targetFramework という名前の属性があり、0 個以上の <dependency> 要素が含まれています。 これらの依存関係は、ターゲット フレームワークがプロジェクトのフレームワーク プロファイルと互換性がある場合に一緒にインストールされます。 正確 なフレームワーク 識別子については、「ターゲット フレームワーク」を参照してください。
lib/ フォルダーと ref/ フォルダー内のファイルには、ターゲット フレームワーク モニカー (TFM) ごとに 1 つのグループを使用することをお勧めします。
次の例は、 <group> 要素のさまざまなバリエーションを示しています。
<dependencies>
<group targetFramework="net472">
<dependency id="jQuery" version="1.10.2" />
<dependency id="WebActivatorEx" version="2.2.0" />
</group>
<group targetFramework="net20">
</group>
</dependencies>
使用する NuGet ターゲットの決定
ポータブル クラス ライブラリを対象とするライブラリをパッケージ化する場合、特に PCL のサブセットのみを対象とする場合は、フォルダー名と .nuspec ファイルで使用する必要がある NuGet ターゲットを決定するのが難しい場合があります。 これを行うには、次の外部リソースが役立ちます。
- .NET のフレームワーク プロファイル (stephencleary.com)
- ポータブル クラス ライブラリ プロファイル (plnkr.co): PCL プロファイルとその同等の NuGet ターゲットを列挙するテーブル
- ポータブル クラス ライブラリ プロファイル ツール (github.com): システムで使用可能な PCL プロファイルを決定するためのコマンド ライン ツール
コンテンツ ファイルと PowerShell スクリプト
Warnung
変更可能なコンテンツ ファイルとスクリプトの実行は、 packages.config 形式でのみ使用できます。他のすべての形式では非推奨となり、新しいパッケージには使用しないでください。
packages.configでは、コンテンツ ファイルと PowerShell スクリプトは、contentフォルダーとtools フォルダー内の同じフォルダー規則を使用して、ターゲット フレームワークによってグループ化できます。 例えば次が挙げられます。
\content
\net46
\MyContent.txt
\net461
\MyContent461.txt
\uap
\MyUWPContent.html
\netcore
\tools
init.ps1
\net46
install.ps1
uninstall.ps1
\uap
install.ps1
uninstall.ps1
フレームワーク フォルダーが空のままの場合、NuGet はアセンブリ参照やコンテンツ ファイルを追加したり、そのフレームワークの PowerShell スクリプトを実行したりしません。
注
init.ps1はソリューション レベルで実行され、プロジェクトに依存しないため、tools フォルダーのすぐ下に配置する必要があります。 フレームワーク フォルダーの下に配置された場合は無視されます。