.NET プロジェクト SDK
最新の .NET プロジェクトは、プロジェクト ソフトウェア開発キット (SDK) に関連付けられています。 各 "プロジェクト SDK" は、MSBuild ターゲット と、コードのコンパイル、パッキング、発行を行う関連する タスク のセットです。 プロジェクト SDK を参照するプロジェクトは、"SDK スタイルのプロジェクト" と呼ばれることもあります。
使用可能な SDK
次の SDK を利用できます。
ID | 説明 | リポジトリ |
---|---|---|
Microsoft.NET.Sdk |
.NET SDK | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.Web |
.NET Web SDK | https://github.com/dotnet/sdk |
Microsoft.NET.Sdk.Razor |
.NET Razor SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.BlazorWebAssembly |
.NET Blazor WebAssembly SDK | https://github.com/dotnet/aspnetcore |
Microsoft.NET.Sdk.Worker |
.NET Worker Service SDK | |
Aspire.AppHost.Sdk |
.NET Aspire SDK | https://github.com/dotnet/aspire |
MSTest.Sdk |
MSTest SDK | https://github.com/microsoft/testfx |
.NET SDK は、.NET の基本 SDK です。 その他の SDK からは .NET SDK が参照され、その他の SDK に関連付けられているプロジェクトでは、すべての .NET SDK プロパティが使用可能になります。 たとえば、Web SDK は、.NET SDK と Razor SDK の両方に依存しています。
NuGet を使用して配布できる独自の SDK を作成することもできます。
Windows フォームおよび Windows Presentation Foundation (WPF) プロジェクトの場合、.NET SDK (Microsoft.NET.Sdk
) を指定し、プロジェクト ファイルでいくつかの追加プロパティを設定します。 詳細については、「.NET デスクトップ SDK を有効にする」を参照してください。
プロジェクト ファイル
.NET プロジェクトは、 MSBuild 形式に基づいています。 プロジェクト ファイルは、C# プロジェクトでは .csproj、F# プロジェクトでは .fsproj のような拡張子が付いていて、XML 形式です。 MSBuild プロジェクト ファイルのルート要素は、 Project 要素です。 Project
要素には、使用する SDK (およびバージョン) を指定する省略可能な Sdk
属性があります。 .NET ツールを使用してコードをビルドするには、 Sdk
属性を、「使用可能な SDK」の表にあるいずれかの ID に設定します。
<Project Sdk="Microsoft.NET.Sdk">
...
</Project>
.NET Aspire 9 以降では、上の例での指定に .NET Aspire SDK を使用できます。
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0-rc.1.24511.1" />
<!-- Omitted for brevity... -->
</Project>
詳細については、.NET Aspire のツールとセットアップに関する記事を参照してください。
NuGet から取得した SDK を指定するには、名前の末尾にバージョンを含めるか、 global.json ファイルに名前とバージョンを指定します。
<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
...
</Project>
SDK を指定するもう 1 つの方法として、トップレベルの Sdk
要素を使用する方法があります。
<Project>
<Sdk Name="Microsoft.NET.Sdk" />
...
</Project>
これらの方法のいずれかで SDK を参照すると、.NET のプロジェクト ファイルが大幅に簡素化されます。 プロジェクトの評価中に、MSBuild によってプロジェクト ファイルの先頭に Sdk.props
の暗黙的なインポートと、末尾に Sdk.targets
の暗黙的なインポートが追加されます。
<Project>
<!-- Implicit top import -->
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
...
<!-- Implicit bottom import -->
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>
ヒント
Windows コンピューターでは、 Sdk.props ファイルと Sdk.targets ファイルは %ProgramFiles%\dotnet\sdk\[バージョン]\Sdks\Microsoft.NET.Sdk\Sdk フォルダーにあります。
プロジェクト ファイルの前処理
MSBuild では、 dotnet msbuild -preprocess
コマンドを使用して、SDK とそのターゲットが取り込まれた後の完全に展開されたプロジェクトがどのようになるかを確認できます。 dotnet msbuild
コマンドの preprocess スイッチによって、インポートされるファイル、そのソース、ビルドに対するそのコントリビューションが、実際にプロジェクトをビルドすることなく、表示されます。
プロジェクトにターゲット フレームワークが複数存在する場合は、1 つのフレームワークだけにコマンドの結果を集中させてください。そのためには、そのフレームワークを MSBuild プロパティとして指定します。 次に例を示します。
dotnet msbuild -property:TargetFramework=net8.0 -preprocess:output.xml
既定で含まれるものと除外されるもの
Compile
項目、 埋め込みリソース、 None
項目 に既定で含まれるものと除外されるものが SDK で定義されています。 SDK 以外の .NET Framework プロジェクトとは異なり、既定値がほとんどの一般的なユース ケースに対応しているため、これらの項目をプロジェクト ファイルで指定する必要はありません。 この動作により、プロジェクト ファイルのサイズがより小さく、より簡単に理解できるようになり、必要に応じて手作業で編集できます。
次の表は、.NET SDK に組み込まれる、および除外される要素と glob の一覧を示します。
要素 | 含まれる glob | 除外される glob | glob の削除 |
---|---|---|---|
Compile | **/*.cs (または他の言語拡張機能) | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | 該当なし |
EmbeddedResource | **/*.resx | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | 該当なし |
None | **/* | **/*.user; **/*.*proj; **/*.sln; **/*.vssscc | **/*.cs; **/*.resx |
Note
./bin
フォルダーと ./obj
フォルダーは、 $(BaseOutputPath)
と $(BaseIntermediateOutputPath)
の MSBuild プロパティによって表され、既定で glob から除外されます。 除外されるものは、 DefaultItemExcludes プロパティによって表されます。
.NET デスクトップ SDK には、WPF に含まれるものと除外されるものが追加されています。 詳細については、「WPF に含まれるものと除外されるもの」を参照してください。
プロジェクト ファイルでこれらの項目を明示的に定義すると、 NETSDK1022 ビルド エラーが発生する可能性があります。 このエラーを解決する方法については、「NETSDK1022: 重複する項目が含まれていました」を参照してください。
暗黙的な using ディレクティブ
.NET 6 以降、暗黙的な global using
ディレクティブ が新しい C# プロジェクトに追加されます。 これは、完全修飾名を指定したり、 using
ディレクティブを手動で追加したりしなくても、これらの名前空間で定義された型を使用できることを意味します。 暗黙的な 側面とは、プロジェクトの obj ディレクトリに生成されるファイルに global using
ディレクティブが追加されるという事実を指します。
次のいずれかの SDK を使用するプロジェクトには、暗黙的な global using
ディレクティブが追加されます。
Microsoft.NET.Sdk
Microsoft.NET.Sdk.Web
Microsoft.NET.Sdk.Worker
Microsoft.NET.Sdk.WindowsDesktop
global using
ディレクティブは、プロジェクトの SDK に基づく一連の既定の名前空間の名前空間ごとに追加されます。 これらの既定の名前空間を次の表に示します。
SDK | 既定の名前空間 |
---|---|
Microsoft.NET.Sdk | System System.Collections.Generic System.IO System.Linq System.Net.Http System.Threading System.Threading.Tasks |
Microsoft.NET.Sdk.Web | Microsoft.NET.Sdk 名前空間 System.Net.Http.Json Microsoft.AspNetCore.Builder Microsoft.AspNetCore.Hosting Microsoft.AspNetCore.Http Microsoft.AspNetCore.Routing Microsoft.Extensions.Configuration Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Hosting Microsoft.Extensions.Logging |
Microsoft.NET.Sdk.Worker | Microsoft.NET.Sdk 名前空間 Microsoft.Extensions.Configuration Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Hosting Microsoft.Extensions.Logging |
Microsoft.NET.Sdk.WindowsDesktop (Windows Forms) | Microsoft.NET.Sdk 名前空間 System.Drawing System.Windows.Forms |
Microsoft.NET.Sdk.WindowsDesktop (WPF) | Microsoft.NET.Sdk 名前空間 System.IO 削除済み System.Net.Http 削除済み |
この機能を無効にする場合、または既存の C# プロジェクトで暗黙的な global using
ディレクティブを有効にする場合は、 ImplicitUsings
MSBuild プロパティを使用して実行できます。
必要に応じて、プロジェクト ファイルに Using
項目 (Visual Basic プロジェクトの場合は Import
項目) を追加することによって暗黙的な global using
ディレクティブを指定できます。次に例を示します。
<ItemGroup>
<Using Include="System.IO.Pipes" />
</ItemGroup>
暗黙的なパッケージ参照
プロジェクトで .NET Standard 1.0 から 2.0 をターゲットとする場合、.NET SDK により、特定の "メタパッケージ" への暗黙的な参照が追加されます。 メタパッケージは、他のパッケージの依存関係のみで構成されるフレームワーク ベースのパッケージです。 メタパッケージは、プロジェクト ファイルの TargetFramework または TargetFrameworks (plural) プロパティで指定されたターゲット フレームワークに基づいて暗黙的に参照されます。
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
</PropertyGroup>
必要に応じて、 DisableImplicitFrameworkReferences プロパティを使用して暗黙的なパッケージ参照を無効にし、必要なフレームワークまたはパッケージのみに明示的な参照を追加することができます。
レコメンデーション:
- .NET Framework または .NET Standard 1.0 から 2.0 をターゲットとする場合は、プロジェクト ファイルの
<PackageReference>
項目を使用してNETStandard.Library
メタパッケージへの明示的な参照を追加しないでください。 .NET Standard 1.0 から 2.0 プロジェクトの場合、これらのメタパッケージは暗黙的に参照されます。 .NET Framework プロジェクトの場合、.NET Standard ベースの NuGet パッケージを使用する場合、何らかのバージョンのNETStandard.Library
が必要であれば、NuGet はそのバージョンを自動的にインストールします。 - .NET Standard 1.0 から 2.0 をターゲットとする場合に、特定バージョンの
NETStandard.Library
メタパッケージが必要であれば、<NetStandardImplicitPackageVersion>
プロパティを使用し、必要なバージョンを設定できます。
ビルド イベント
SDK スタイルのプロジェクトでは、 PreBuild
または PostBuild
という名前の MSBuild ターゲットを使用し、 PreBuild
の BeforeTargets
プロパティまたは PostBuild
の AfterTargets
プロパティを設定します。
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command=""$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"" />
</Target>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="echo Output written to $(TargetDir)" />
</Target>
Note
- MSBuild ターゲットには任意の名前を使用できます。 ただし、
PreBuild
およびPostBuild
ターゲットは Visual Studio IDE によって認識されるため、これらの名前を使用することにより、IDE でコマンドを編集できます。 $(ProjectDir)
などのマクロが解決されないため、SDK スタイルのプロジェクトでは、プロパティPreBuildEvent
とPostBuildEvent
は推奨されません。 たとえば、次のようなコードはサポートされません。
<PropertyGroup>
<PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent>
</PropertyGroup>
ビルドのカスタマイズ
ビルドをカスタマイズするには、さまざまな方法があります。 プロパティを引数として msbuild または dotnet コマンドに渡すと、プロパティをオーバーライドできます。 また、プロパティをプロジェクト ファイルに追加することや、 Directory.Build.props ファイルに追加することができます。 .NET プロジェクトの便利なプロパティの一覧については、「.NET SDK プロジェクトの MSBuild リファレンス」をご覧ください。
ヒント
コマンド ラインから新しい Directory.Build.props ファイルを簡単に作成するには、リポジトリのルートにある コマンド dotnet new buildprops
を使用します。
カスタム ターゲット
.NET プロジェクトでは、プロジェクトで使用するカスタムの MSBuild ターゲットとプロパティをパッケージ化し、そのパッケージをプロジェクトで使用することができます。 この種の拡張機能を使用するのは、次の場合です。
- ビルド処理を拡張する。
- ビルド プロセスの成果物 (生成されたファイルなど) にアクセスする。
- どのような構成でビルドが呼び出されるかを検査する。
カスタムのビルド ターゲットまたはプロパティを追加するには、プロジェクトの build フォルダーに <package_id>.targets
または <package_id>.props
の形式のファイル (たとえば Contoso.Utility.UsefulStuff.targets
) を配置します。
次の XML は .csproj ファイルからのスニペットです。パッケージ化する対象を dotnet pack
コマンドに指示しています。 <ItemGroup Label="dotnet pack instructions">
要素で、パッケージ内の build フォルダーにターゲット ファイルを配置します。 <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
要素で、アセンブリと .json ファイルを build フォルダーに配置します。
<Project Sdk="Microsoft.NET.Sdk">
...
<ItemGroup Label="dotnet pack instructions">
<Content Include="build\*.targets">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
<Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
<!-- Collect these items inside a target that runs after build but before packaging. -->
<ItemGroup>
<Content Include="$(OutputPath)\*.dll;$(OutputPath)\*.json">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
</Target>
...
</Project>
プロジェクトでカスタム ターゲットを使用するには、パッケージとそのバージョンを指す PackageReference
要素を追加します。 ツールとは異なり、カスタム ターゲットのパッケージは、それを使用するプロジェクトの依存関係クロージャに含まれます。
カスタム ターゲットの使用方法を構成できます。 それは MSBuild ターゲットであるため、指定されたターゲットに依存することや、別のターゲットの後に実行したり、 dotnet msbuild -t:<target-name>
コマンドを使用して手動で呼び出したりすることができます。 ただし、優れたユーザー エクスペリエンスを提供するために、プロジェクトごとのツールとカスタム ターゲットを組み合わせることができます。 このシナリオでは、必要なすべてのパラメーターをプロジェクトごとのツールで受け取り、受け取ったパラメーターを、ターゲットを実行する必要な dotnet msbuild
の呼び出しに変換します。 このような相乗効果のサンプルは、 dotnet-packer
プロジェクトの「MVP Summit 2016 Hackathon samples」 (MVP Summit 2016 ハッカソンのサンプル) レポートで参照することができます。
関連項目
.NET