What you're asking for is known as "transitive packages". If ProjB uses PackageReference, then it will automatically get all of ProjA's packages as transitive packages. However, if ProjB is not using PackageReference, then NuGet doesn't support transitive packages.
If ProjB has packages installed with packages.config, the project must be migrated to PackageReference. For many project types, like class libraries, console apps, WPF projects, and others, there's generally no problems, but there are some package compatibility differences, and some project types that don't support PackageReference at all, so it might not be trivial to switch: https://learn.microsoft.com/nuget/consume-packages/migrate-packages-config-to-package-reference
Otherwise, it means that ProjB doesn't reference any packages directly, in which case there are 3 options:
Recommended: Use SDK style project
All SDK styles are PackageReference only, they don't support packages.config.
Understanding target framework and project format isn't trivial, and I guess in order to reduce confusion, the decision makers in Visual Studio decided to call non-SDK style project templates ".NET Framework", and to call SDK style project templates ".NET" (previously .NET Core). However, SDK style projects can target .NET Framework, and if you do that, you can benefit from all the newer tools in the dotnet
CLI.
Within Visual Studio, the easiest way to create a SDK style project, targeting .NET Framework, is to create a new .NET project, then edit the project file. With SDK style projects, you no longer need to unload the project either, right clicking the project and select Edit Project, or simply single left clicking the project in Solution Explorer will open the project XML in a code window. Change <TargetFramework>net6.0</TargetFramework>
to <TargetFramework>net48</TargetFramework>
.
A minimal SDK ClassLibrary project is as follows:
<Project>
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
</Project>
To make this a console app, add <OutputType>exe</OutputType>
inside the PropertyGroup
.
SDK style projects automatically "glob" **/*.cs
, so there's no longer a need for projects to list every file in the project individually, as you see in non-SDK style projects.
Alternative 1: Install a package with PackageReference
Install a package, any package, and make sure it's using PackageReference (before installing the package, there's two choices in Tools->Options, NuGet Package Manager->General. I like to enable "prompt on first package install"). If your project is in source control, consider installing the appropriate SourceLink for your repo location. For example, Microsoft.SourceLink.GitHub. To automatically do this for all projects in the repo, create a Directory.Build.props
in your repo root, if you haven't got one already, and make this its contents:
<Project>
<ItemGroup Condition=" '$(MSBuildProjectExtension)' == '.csproj' ">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
</ItemGroup>
</Project>
This way, every csproj in the repo will include this PackageReference, and NuGet will therefore transitively flow all ProjectReference
s.
Alternative 2: Explicitly tell NuGet what restore style to use.
If your project is some project type that is not supported as SDK style, for example UWP projects, or Visual Studio Extension (VSIX) projects, or .NET Framework ASP.NET projects (keep in mind, PackageReference doesn't support content
files in packages like packages.config does, so PackageReference will require non-trivial migration for these types of projects), then adding an MSBuild property <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
will work. If you don't want to manually do this on all your project files, then create a Directory.Build.props
file in your repo root with contents:
<Project>
<PropertyGroup Condition=" '$(MSBuildProjectExtension)' == '.csproj' ">
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<PropertyGroup>
</Project>
Note, if you have any projects in the repo that use packages.config, this will cause NuGet to stop using the packages.config file. Since MSBuild is a programming language, there's many ways you can resolve this. For example, by setting <RestoreProjectStyle>PackagesConfig</RestoreProjectStyle>
in your project file, which will overwrite the value inherited from Directory.Build.props
.