Latest Changes In Nuget 4.x With Dotnet CLI

If you’re up to date on your dotnet tooling, then you are probably using the very latest Dotnet Nuget command (dotnet add package). And then on top of that you are wondering where the hell are all your packages, and where is your packages.config? I know atleast for me it was extremely confusing adding a nuget package and not seeing a packages folder fill up. So let’s run through some of the changes.

What Is The Dotnet CLI Command “dotnet add package” Actually Doing?

So when you run the command “dotnet add package”, what is it doing under the hood? Well actually, when it boils down to it, it’s actually just forwarding your command to the “nuget.exe” anyway. If you dig into the source code eventually you end up at a class called “NugetForwardingApp” (Source) that takes your dotnet command and transforms it to the original nuget command anyway. This makes sense as nuget will still be used with the .net full framework so it’s pointless for the .net core team to completely rebuild a package manager from scratch right?

As a side note, you’ll often find this with dotnet CLI commands. Often they are just a wrapper or a skin over things like nuget or msbuild to make your life a little easier (Because who hasn’t wasted a day trying to get a finicky msbuild command to work!).

Where Is My packages.config?

Previously when you added a nuget package, you would end up with a packages.config file in the root of your project directory that told nuget what dependencies you had. You’ll quickly notice that this is not the case anymore, so where are your dependencies defined? In the .csproj of course. Let’s say I create a new project with a reference to EntityFramework, my csproj would look a bit like the following :

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

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.1" />
  </ItemGroup>
</Project>

The csproj format that is used for .net core projects is now very very clean, so it makes viewing your dependencies as easy as viewing your packages.json. The other benefit is that you have all your dependencies in a single file. When you add project references (Or hardcoded DLL references), it’s all contained within the csproj.

Where Is My Packages Folder?

You are probably used to having a packages folder in your solution that holds the nuget downloads. This is now gone and been replaced by a global packages folder. By default this is located at “%userprofile%\.nuget\packages”. Opening this folder the first time might give you a heart attack with how much is in here, and I suspect that “cleaning” this folder in the future is going to be the fix for various bugs.

It certainly makes sense to have a global folder on some levels though as for many projects you will be using the exact same version of the same library across many projects. With ASP.net core itself being inside nuget, it also makes sense to not have to download this over and over for each project.

It’s also important to note that the location of “%userprofile%\.nuget\packages” is just the default, you are able to edit your nuget.config either on the global level or per project level to specify another location. But be aware if you do this on the project level and give each project it’s own packages folder, you will download all of ASP.net core into that packages folder all over again.

What Happens When I Publish?

When it comes to publishing, there is really nothing to worry about. When you publish, .net core works out what packages you need and moves them into your publish destination folder for a stand alone solution. You don’t for example need this packages folder on your server, it’s only for development purposes.

Editing Nuget.config

As discussed earlier, you can edit your nuget.config file to change your local global cache location, add nuget feeds, and configure other settings such as HTTP Proxies, default package versions etc. The Microsoft documentation for editing your nuget.config can be found here. A handy tip to generating a nuget file at the project level is the following command from a command line/bash/terminal.

dotnet new nuget

Be aware that adding a nuget file at the project level (even a completely empty one) can have bad side effects. I’ve found that settings don’t exactly “fall through”, e.g. If a setting is missing from the project level nuget.config, it doesn’t then go to the global config, it just treats it as false/missing etc.

Leave a Comment