MSBuild breaking changes in .NET Core 2.1 - 3.1

The following breaking changes are documented on this page:

Breaking change Version introduced
Design-time builds only return top-level package references 3.1
Resource manifest file name change 3.0
Project tools now included in SDK 2.1

.NET Core 3.1

Design-time builds only return top-level package references

Starting in .NET Core SDK 3.1.400, only top-level package references are returned by the RunResolvePackageDependencies target.

Version introduced

.NET Core SDK 3.1.400

Change description

In previous versions of the .NET Core SDK, the RunResolvePackageDependencies target created the following MSBuild items that contained information from the NuGet assets file:

  • PackageDefinitions
  • PackageDependencies
  • TargetDefinitions
  • FileDefinitions
  • FileDependencies

This data is used by Visual Studio to populate the Dependencies node in Solution Explorer. However, it can be a large amount of data, and the data isn't needed unless the Dependencies node is expanded.

Starting in the .NET Core SDK version 3.1.400, most of these items aren't generated by default. Only items of type Package are returned. If Visual Studio needs the items to populate the Dependencies node, it reads the information directly from the assets file.

Reason for change

This changed was introduced to improve solution-load performance inside of Visual Studio. Previously, all package references would be loaded, which involved loading many references that most users would never view.

If you have MSBuild logic that depends on these items being created, set the EmitLegacyAssetsFileItems property to true in your project file. This setting enables the previous behavior where all the items are created.

Category

MSBuild

Affected APIs

N/A


.NET Core 3.0

Resource manifest file name change

Starting in .NET Core 3.0, in the default case, MSBuild generates a different manifest file name for resource files.

Version introduced

3.0

Change description

Prior to .NET Core 3.0, if no LogicalName, ManifestResourceName, or DependentUpon metadata was specified for an EmbeddedResource item in the project file, MSBuild generated a manifest file name in the pattern <RootNamespace>.<ResourceFilePathFromProjectRoot>.resources. If RootNamespace is not defined in the project file, it defaults to the project name. For example, the generated manifest name for a resource file named Form1.resx in the root project directory was MyProject.Form1.resources.

Starting in .NET Core 3.0, if a resource file is colocated with a source file of the same name (for example, Form1.resx and Form1.cs), MSBuild uses type information from the source file to generate the manifest file name in the pattern <Namespace>.<ClassName>.resources. The namespace and class name are extracted from the first type in the colocated source file. For example, the generated manifest name for a resource file named Form1.resx that's colocated with a source file named Form1.cs is MyNamespace.Form1.resources. The key thing to note is that the first part of the file name is different to prior versions of .NET Core (MyNamespace instead of MyProject).

Note

If you have LogicalName, ManifestResourceName, or DependentUpon metadata specified on an EmbeddedResource item in the project file, then this change does not affect that resource file.

This breaking change was introduced with the addition of the EmbeddedResourceUseDependentUponConvention property to .NET Core projects. By default, resource files aren't explicitly listed in a .NET Core project file, so they have no DependentUpon metadata to specify how to name the generated .resources file. When EmbeddedResourceUseDependentUponConvention is set to true, which is the default, MSBuild looks for a colocated source file and extracts a namespace and class name from that file. If you set EmbeddedResourceUseDependentUponConvention to false, MSBuild generates the manifest name according to the previous behavior, which combines RootNamespace and the relative file path.

In most cases, no action is required on the part of the developer, and your app should continue to work. However, if this change breaks your app, you can either:

  • Change your code to expect the new manifest name.

  • Opt out of the new naming convention by setting EmbeddedResourceUseDependentUponConvention to false in your project file.

    <PropertyGroup>
      <EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
    </PropertyGroup>
    

Category

MSBuild

Affected APIs

N/A


.NET Core 2.1

Project tools now included in SDK

The .NET Core 2.1 SDK now includes common CLI tooling, and you no longer need to reference these tools from the project.

Change description

In .NET Core 2.0, projects reference external .NET tools with the <DotNetCliToolReference> project setting. In .NET Core 2.1, some of these tools are included with the .NET Core SDK, and the setting is no longer needed. If you include references to these tools in your project, you'll receive an error similar to the following: The tool 'Microsoft.EntityFrameworkCore.Tools.DotNet' is now included in the .NET Core SDK.

Tools now included in .NET Core 2.1 SDK:

<DotNetCliToolReference> value Tool
Microsoft.DotNet.Watcher.Tools dotnet-watch
Microsoft.Extensions.SecretManager.Tools dotnet-user-secrets
Microsoft.Extensions.Caching.SqlConfig.Tools dotnet-sql-cache
Microsoft.EntityFrameworkCore.Tools.DotNet dotnet-ef

Version introduced

.NET Core SDK 2.1.300

Remove the <DotNetCliToolReference> setting from your project.

Category

MSBuild

Affected APIs

N/A