Add Reference to dll vs. adding a NuGet package in .NET Standard project

Stilgar picture Stilgar · Sep 20, 2017 · Viewed 8.5k times · Source

I have a .NET Standard 2.0 project in my solution and I am using the IConfiguration interface. When I write the name VS suggest that I reference Microsoft.Extensions.Configuration.Abstractions.dll. If I do it is added under the reference node. However I can also add it as a NuGet package. Both ways seems to work. I assume that the reference VS suggests is added via the .NET Standard SDK that is referenced in the project.

Which is the recommended way to add that reference? What are the advantages and the disadvantages of each approach?

Answer

Martin Ullrich picture Martin Ullrich · Sep 20, 2017

Referencing a DLL directly from a NuGet package that was downloaded manually, or is installed in a known location, can speed up the restore and build process but has a few dangers.

There are a number of things that a NuGet package can do when referenced that a DLL file cannot. If you want to reference a DLL from a package, make sure that the package does not do one of the following / account for the following possibilities:

  • Additional NuGet packages can be pulled in as dependencies. If you upgrade the DLL from a newer package, you need to check if dependencies have changed and update the project accordingly.
  • NuGet packages can provide different reference and implementation assemblies - e.g. a NuGet package may give an "API surface" dll in its ref/ folder and then contain different implementation assemblies for .NET Framework .NET Core, Xamarin and more in its lib/. folder. You have to be careful to select the correct DLL file to reference for the project type - a .NET Standard library may need to reference a ref-assembly (e.g. ref/netstandard1.4/foo.dll during compile time and a .NET Framework application that uses this library needs to reference the assembly from e.g. lib/net452/foo.dll.
  • NuGet packages may contain additional runtime-specifics and/or target framework specific content that is added to the build-output. This can be native libraries (.dll on windows, .so on linux etc. - from a runtime/ subfolder) or any content file. Getting this right without NuGet is tricky, since the .nuspec file can also define build actions for content files.
  • Build logic can be included in NuGet packages that set certain properties or execute targets during the build that is necessary for the product to be used correctly. This is impossible to do manually without editing the .csproj file in the right way.

If the NuGet package does not use any of the above (which you need to check manually), you are generally safe to reference the DLL instead. However, updating the DLL and its dependencies is a lot of work and easier to do with NuGet.

Additionally, you mentioned that you reference directly from the nuget fallback folder from the .NET Core tooling. This folder is not guaranteed to contain specific versions of the DLL in other installations (depending on the SDK versions installed) and may even be installed in a different location on different machines, rendering your project file unusable for other people working on it (as well as building on non-windows machines).