Using Package Management Format in Rider

Introducing different Package Management formats:

There are two known MSBuild project file formats – one old (also known as legacy or classic) and one modern. There are also two formats for managing NuGet dependencies. You can use PackageReference items in a project file or you can use a packages.config file, which is a predecessor to the PackageReference.

Just like the modern MSBuild, the modern project type supports only the PackageReference item in a csproj. The old project file type is compatible with both PackageReference and packages.config.

Legacy project files with packages.config

An old project file can be recognized by the massive number of lines it contains, as in the example below:

csproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\EntityFramework.6.4.0\build\EntityFramework.props" Condition="Exists('..\packages\EntityFramework.6.4.0\build\EntityFramework.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7A1F139A-4DC8-4D16-AA04-B972EDD381B4}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ConsoleApplication2</RootNamespace>
<AssemblyName>ConsoleApplication2</AssemblyName>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<HintPath>..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<HintPath>..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

The default way to install NuGet packages in classic projects is to use a packages.config file, which by default can be found near the project file.

packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.4.0" targetFramework="net471" />
<package id="NUnit" version="3.12.0" targetFramework="net471" />
</packages>

Here is an example of how this kind of project looks in Rider:
Screenshot_2020-01-14_at_16.20.29.png

Legacy project files with PackageReference

Instead of managing NuGet packages in a separate location, all the information can be put in a project file in PackageReference items. The project file stays in the old format, but it uses the new package management format:

csproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')"/>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A4944066-8F7A-4950-A6BF-394C29144B42}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ConsoleApplication3</RootNamespace>
<AssemblyName>ConsoleApplication3</AssemblyName>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System"/>
<Reference Include="System.Core"/>
<Reference Include="System.Data"/>
<Reference Include="System.Xml"/>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs"/>
<Compile Include="Properties\AssemblyInfo.cs"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3"/>
<PackageReference Include="NUnit" Version="3.12.0"/>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"/>
</Project>

And here’s an example of how this kind of project would look in Rider:
Screenshot_2020-01-26_at_18.11.55.png

NOTE: Only the latest versions of MSBuild support PackageReference. Using an old MSBuild version may lead to some problems with PackageReference.

Modern project files with PackageReference

The modern project file type is the default option when using .NET Core SDK. These project files only support the use of PackageReference items for managing NuGet packages.

csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
</ItemGroup>
</Project>

Here is an example of how this kind of project looks in Rider:
Screenshot_2020-01-13_at_00.11.38.png

NOTE: Only the latest versions of MSBuild support PackageReference. Using an old MSBuild version may lead to some problems with PackageReference.

How Rider detects package settings

Modern project file

If your project has a modern project file, only PackageReference items can be used for the package management format. But remember that only the latest versions of MSBuild support PackageReference. Using an old MSBuild version may lead to some problems with PackageReference.

Legacy project file

In contrast to the modern project file, which only supports PackageReference, the old project file format is compatible with both PackageReference and packages.config. Let’s see how Rider selects which one to use to restore NuGet packages:

  1. If a packages.config file exists Rider uses it.
  2. If there is no packages.config file, and a project file contains at least one PackageReference item, Rider uses PackageReference.
  3. If there aren’t any PackageReference items and there isn’t a packages.config file, and you want to install the first NuGet package, Rider will select the package management format according to the following algorithm:
    1. First, it will search for the RestoreProjectStyle MSBuild property <RestoreProjectStyle>PackageReference</RestoreProjectStyle>. If this exists, Rider will use the PackageReference.
    2. If the RestoreProjectStyle property is not present, Rider uses the format specified in its settings under “Preferences | Build, Execution, Deployment | NuGet -> [ ] Default package management format.” Screenshot_2020-01-13_at_01.55.42.png
  4. If your classic project contains both packages.config file and PackageReference items and you open it in Rider or VisualStudio for the first time, NuGet dependencies from PackageReference items will be used and packages.config file will be ignored despite the settings.

References

You can find more details here:

Please sign in to leave a comment.

Have more questions?

Submit a request