Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft EdgeMore info about Internet Explorer and Microsoft Edge
Table of contentsExit editor mode

.NET project SDKs

Feedback

In this article

Modern .NET projects are associated with a project software development kit (SDK). Eachproject SDK is a set of MSBuildtargets and associatedtasks that are responsible for compiling, packing, and publishing code. A project that references a project SDK is sometimes referred to as anSDK-style project.

Available SDKs

The available SDKs include:

IDDescriptionRepo
Microsoft.NET.SdkThe .NET SDKhttps://github.com/dotnet/sdk
Microsoft.NET.Sdk.WebThe .NETWeb SDKhttps://github.com/dotnet/sdk
Microsoft.NET.Sdk.RazorThe .NETRazor SDKhttps://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.BlazorWebAssemblyThe .NETBlazor WebAssembly SDKhttps://github.com/dotnet/aspnetcore
Microsoft.NET.Sdk.WorkerThe .NETWorker Service SDKhttps://github.com/dotnet/aspnetcore
Aspire.AppHost.SdkThe .NETAspire SDKhttps://github.com/dotnet/aspire
MSTest.SdkTheMSTest SDKhttps://github.com/microsoft/testfx

The .NET SDK is the base SDK for .NET. The other SDKs reference the .NET SDK, and projects that are associated with the other SDKs have all the .NET SDK properties available to them. The Web SDK, for example, depends on both the .NET SDK and the Razor SDK.

For Windows Forms and Windows Presentation Foundation (WPF) projects, you specify the .NET SDK (Microsoft.NET.Sdk) and set some additional properties in the project file. For more information, seeEnable .NET Desktop SDK.

MSBuild SDKs, which you can use to configure and extend your build, are listed atMSBuild SDKs.

You can also author your own SDK that can be distributed via NuGet.

Project files

.NET projects are based on theMSBuild format. Project files, which have extensions like.csproj for C# projects and.fsproj for F# projects, are in XML format. The root element of an MSBuild project file is theProject element. TheProject element has an optionalSdk attribute that specifies which SDK (and version) to use. To use the .NET tools and build your code, set theSdk attribute to one of the IDs in theAvailable SDKs table.

<Project Sdk="Microsoft.NET.Sdk">    <!-- Omitted for brevity... --></Project>

TheProject/Sdk attribute andSdk element enable additive SDKs. Consider the following example, where the Aspire SDK (Aspire.AppHost.Sdk) is added to the project atop theMicrosoft.NET.Sdk:

<Project Sdk="Microsoft.NET.Sdk">    <Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />    <!-- Omitted for brevity... --></Project>

In the preceding project file, both SDKs are used to resolve dependencies in an additive nature. For more information, seeAspire SDK.

To specify an SDK that comes from NuGet, include the version at the end of the name, or specify the name and version in theglobal.json file.

<Project Sdk="MSBuild.Sdk.Extras/2.0.54">  ...</Project>

Another way to specify the SDK is with the top-levelSdk element:

<Project>  <Sdk Name="Microsoft.NET.Sdk" />  ...</Project>

Referencing an SDK in one of these ways greatly simplifies project files for .NET. While evaluating the project, MSBuild adds implicit imports forSdk.props at the top of the project file andSdk.targets at the bottom.

<Project>  <!-- Implicit top import -->  <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />  ...  <!-- Implicit bottom import -->  <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" /></Project>

Tip

On a Windows machine, theSdk.props andSdk.targets files can be found in the%ProgramFiles%\dotnet\sdk\[version]\Sdks\Microsoft.NET.Sdk\Sdk folder.

Preprocess the project file

You can see the fully expanded project as MSBuild sees it after the SDK and its targets are included by using thedotnet msbuild -preprocess command. Thepreprocess switch of thedotnet msbuild command shows which files are imported, their sources, and their contributions to the build without actually building the project.

If the project has multiple target frameworks, focus the results of the command on only one framework by specifying it as an MSBuild property. For example:

dotnet msbuild -property:TargetFramework=net8.0 -preprocess:output.xml

Default includes and excludes

The default includes and excludes forCompile items,embedded resources, andNone items are defined in the SDK. Unlike non-SDK .NET Framework projects, you don't need to specify these items in your project file, because the defaults cover most common use cases. This behavior makes the project file smaller and easier to understand and edit by hand, if needed.

The following table shows which elements and whichglobs are included and excluded in the .NET SDK:

ElementInclude globExclude globRemove glob
Compile**/*.cs (or other language extensions)**/*.user; **/*.*proj; **/*.sln(x); **/*.vsssccN/A
EmbeddedResource**/*.resx**/*.user; **/*.*proj; **/*.sln(x); **/*.vsssccN/A
None**/***/*.user; **/*.*proj; **/*.sln(x); **/*.vssscc**/*.cs; **/*.resx

Note

The./bin and./obj folders, which are represented by the$(BaseOutputPath) and$(BaseIntermediateOutputPath) MSBuild properties, are excluded from the globs by default. Excludes are represented by theDefaultItemExcludes property.

The .NET Desktop SDK has additional includes and excludes for WPF. For more information, seeWPF default includes and excludes.

If you explicitly define any of these items in your project file, you're likely to get aNETSDK1022 build error. For information about how to resolve the error, seeNETSDK1022: Duplicate items were included.

Implicit using directives

Starting in .NET 6, implicitglobal using directives are added to new C# projects. This means that you can use types defined in these namespaces without having to specify their fully qualified name or manually add ausing directive. Theimplicit aspect refers to the fact that theglobal using directives are added to a generated file in the project'sobj directory.

Implicitglobal using directives are added for projects that use one of the following SDKs:

  • Microsoft.NET.Sdk
  • Microsoft.NET.Sdk.Web
  • Microsoft.NET.Sdk.Worker
  • Microsoft.NET.Sdk.WindowsDesktop

Aglobal using directive is added for each namespace in a set of default namespaces that are based on the project's SDK. These default namespaces are shown in the following table.

SDKDefault namespaces
Microsoft.NET.SdkSystem
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading
System.Threading.Tasks
Microsoft.NET.Sdk.WebMicrosoft.NET.Sdk namespaces
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.WorkerMicrosoft.NET.Sdk namespaces
Microsoft.Extensions.Configuration
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Hosting
Microsoft.Extensions.Logging
Microsoft.NET.Sdk.WindowsDesktop (Windows Forms)Microsoft.NET.Sdk namespaces
System.Drawing
System.Windows.Forms
Microsoft.NET.Sdk.WindowsDesktop (WPF)Microsoft.NET.Sdk namespaces
RemovedSystem.IO
RemovedSystem.Net.Http

If you want to disable this feature, or if you want to enable implicitglobal using directives in an existing C# project, you can do so via theImplicitUsings MSBuild property.

You can specify additional implicitglobal using directives by addingUsing items (orImport items for Visual Basic projects) to your project file, for example:

<ItemGroup>  <Using Include="System.IO.Pipes" /></ItemGroup>

Note

Starting with the .NET 8 SDK,System.Net.Http isno longer included inMicrosoft.NET.Sdk when targeting .NET Framework.

Implicit package references

When your project targets .NET Standard 1.0-2.0, the .NET SDK adds implicit references to certainmetapackages. A metapackage is a framework-based package that consists only of dependencies on other packages. Metapackages are implicitly referenced based on the target frameworks specified in theTargetFramework orTargetFrameworks (plural) property of your project file.

<PropertyGroup>  <TargetFramework>netstandard2.0</TargetFramework></PropertyGroup>
<PropertyGroup>  <TargetFrameworks>netstandard2.0;net462</TargetFrameworks></PropertyGroup>

If needed, you can disable implicit package references using theDisableImplicitFrameworkReferences property, and add explicit references to just the frameworks or packages you need.

Recommendations:

  • When targeting .NET Framework or .NET Standard 1.0-2.0, don't add an explicit reference to theNETStandard.Library metapackages via a<PackageReference> item in your project file. For .NET Standard 1.0-2.0 projects, these metapackages are implicitly referenced. For .NET Framework projects, if any version ofNETStandard.Library is needed when using a .NET Standard-based NuGet package, NuGet automatically installs that version.
  • If you need a specific version of theNETStandard.Library metapackage when targeting .NET Standard 1.0-2.0, you can use the<NetStandardImplicitPackageVersion> property and set the version you need.

Build events

In SDK-style projects, use an MSBuild target namedPreBuild orPostBuild and set theBeforeTargets property forPreBuild or theAfterTargets property forPostBuild.

<Target Name="PreBuild" BeforeTargets="PreBuildEvent">    <Exec Command="&quot;$(ProjectDir)PreBuildEvent.bat&quot; &quot;$(ProjectDir)..\&quot; &quot;$(ProjectDir)&quot; &quot;$(TargetDir)&quot;" /></Target><Target Name="PostBuild" AfterTargets="PostBuildEvent">   <Exec Command="echo Output written to $(TargetDir)" /></Target>

Note

  • You can use any name for the MSBuild targets. However, the Visual Studio IDE recognizesPreBuild andPostBuild targets, so by using those names, you can edit the commands in the IDE.
  • The propertiesPreBuildEvent andPostBuildEvent are not recommended in SDK-style projects, because macros such as$(ProjectDir) aren't resolved. For example, the following code is not supported:
<PropertyGroup>  <PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)"</PreBuildEvent></PropertyGroup>

Customize the build

There are various ways tocustomize a build. You might want to override a property by passing it as an argument to themsbuild ordotnet command. You can also add the property to the project file or to aDirectory.Build.props file. For a list of useful properties for .NET projects, seeMSBuild reference for .NET SDK projects.

Tip

An easy way to create a newDirectory.Build.props file from the command line is by using the commanddotnet new buildprops at the root of your repository.

Custom targets

.NET projects can package custom MSBuild targets and properties for use by projects that consume the package. Use this type of extensibility when you want to:

  • Extend the build process.
  • Access artifacts of the build process, such as generated files.
  • Inspect the configuration under which the build is invoked.

You add custom build targets or properties by placing files in the form<package_id>.targets or<package_id>.props (for example,Contoso.Utility.UsefulStuff.targets) in thebuild folder of the project.

The following XML is a snippet from a.csproj file that instructs thedotnet pack command what to package. The<ItemGroup Label="dotnet pack instructions"> element places the targets files into thebuild folder inside the package. The<Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles"> element places the assemblies and.json files into thebuild folder.

<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>

To consume a custom target in your project, add aPackageReference element that points to the package and its version. Unlike the tools, the custom targets package is included in the consuming project's dependency closure.

You can configure how to use the custom target. Since it's an MSBuild target, it can depend on a given target, run after another target, or be manually invoked by using thedotnet msbuild -t:<target-name> command. However, to provide a better user experience, you can combine per-project tools and custom targets. In this scenario, the per-project tool accepts whatever parameters are needed and translates that into the requireddotnet msbuild invocation that executes the target. You can see a sample of this kind of synergy on theMVP Summit 2016 Hackathon samples repo in thedotnet-packer project.

See also

Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, seeour contributor guide.

Feedback

Was this page helpful?

YesNoNo

Need help with this topic?

Want to try using Ask Learn to clarify or guide you through this topic?

Suggest a fix?

  • Last updated on

In this article

Was this page helpful?

YesNo
NoNeed help with this topic?

Want to try using Ask Learn to clarify or guide you through this topic?

Suggest a fix?