.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 웹 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 |
The .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 속성을 사용할 수 있습니다. 예를 들어 웹 SDK는 .NET SDK 및 Razor SDK에 종속됩니다.
NuGet을 통해 배포할 수 있는 고유한 SDK를 작성할 수도 있습니다.
Windows Forms 및 WPF(Windows Presentation Foundation) 프로젝트의 경우 .NET SDK(Microsoft.NET.Sdk
)를 지정하고 프로젝트 파일에서 몇 가지 추가 속성을 설정합니다. 자세한 내용은 .NET Desktop SDK 사용을 참조하세요.
프로젝트 파일
.NET 프로젝트는 MSBuild 형식을 기반으로 합니다. .csproj(C# 프로젝트) 및 .fsproj(F# 프로젝트) 같은 확장명을 가진 프로젝트 파일은 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를 지정하는 또 다른 방법은 최상위 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 폴더에 있습니다.
프로젝트 파일 전처리
dotnet msbuild -preprocess
명령을 사용하여 SDK 및 해당 대상이 포함된 후 MSBuild에서 보는 것처럼 완전히 확장된 프로젝트를 볼 수 있습니다. dotnet msbuild
명령의 preprocess 스위치는 가져온 파일, 해당 소스 및 실제로 프로젝트를 빌드하지 않는 빌드에 대한 기여를 표시합니다.
프로젝트에 대상 프레임워크가 여러 개 있는 경우 명령의 결과는 대상을 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 |
참고 항목
$(BaseOutputPath)
및 $(BaseIntermediateOutputPath)
MSBuild 속성으로 나타내는 ./bin
및 ./obj
폴더는 기본적으로 GLOB에서 제외됩니다. 제외는 DefaultItemExcludes 속성으로 표시됩니다.
.NET Desktop SDK에는 WPF에 대한 추가 포함 및 제외가 있습니다. 자세한 내용은 WPF 기본 포함 및 제외를 참조하세요.
프로젝트 파일에서 이러한 항목을 명시적으로 정의하는 경우 NETSDK1022 빌드 오류가 발생할 수 있습니다. 오류를 해결하는 방법에 대한 자세한 내용은 NETSDK1022: 중복 항목이 포함됨을 참조하세요.
암시적 using 지시문
.NET 6부터 암시적 global using
지시문이 새 C# 프로젝트에 추가됩니다. 즉, 정규화된 이름을 지정하거나 using
지시문을 수동으로 추가하지 않고도 이러한 네임스페이스에 정의된 형식을 사용할 수 있습니다. 암시적 측면은 global using
지시문이 프로젝트의 obj 디렉터리 내 생성된 파일에 추가된다는 사실을 의미합니다.
다음 SDK 중 하나를 사용하는 프로젝트에 암시적 global using
지시문이 추가됩니다.
Microsoft.NET.Sdk
Microsoft.NET.Sdk.Web
Microsoft.NET.Sdk.Worker
Microsoft.NET.Sdk.WindowsDesktop
프로젝트의 SDK를 기반으로 하는 기본 네임스페이스 집합의 각 네임스페이스에 global using
지시문이 추가됩니다. 이러한 기본 네임스페이스는 다음 표에 표시됩니다.
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(복수) 속성에 지정된 대상 프레임워크를 기준으로 암시적으로 참조됩니다.
<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>
참고 항목
- MSBuild 대상에는 원하는 이름을 사용할 수 있습니다. 그러나 Visual Studio IDE는
PreBuild
및PostBuild
대상을 인식하므로 해당 이름을 사용하여 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은 dotnet pack
명령에 패키지할 항목을 알리는 .csproj 파일의 코드 조각입니다. <ItemGroup Label="dotnet pack instructions">
요소는 패키지 내부 build 폴더에 대상 파일을 배치합니다. <Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
요소는 build 폴더에 어셈블리 및 .json 파일을 배치합니다.
<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 샘플 리포지토리에서 확인할 수 있습니다.
참고 항목
.NET