What NuGet Packages Are
NuGet is the package manager for .NET, distributing reusable libraries as .nupkg files that bundle compiled assemblies, metadata, and sometimes build logic or analyzers. Packages are pulled from feeds — nuget.org by default, or private feeds like Azure Artifacts or GitHub Packages — and cached locally in the global-packages folder (typically ~/.nuget/packages) so multiple projects on the same machine share a single copy instead of duplicating binaries.
Cricket analogy: This is like a central kit room shared by an entire franchise such as Mumbai Indians, where equipment (bats, pads) is stored once and issued to whichever squad (project) needs it, instead of every player buying and storing duplicate gear, the way NuGet's global-packages cache avoids duplicating the same package per project.
PackageReference and Version Resolution
Dependencies are declared with <PackageReference Include="..." Version="..." /> elements inside an ItemGroup. NuGet resolves the full dependency graph transitively — if your project references Serilog.AspNetCore, NuGet also pulls in Serilog and Serilog.Sinks.Console automatically — and when two packages request different versions of the same transitive dependency, NuGet applies the 'nearest wins' rule unless you override it explicitly, which can silently upgrade or downgrade a package you never referenced directly.
Cricket analogy: This is like a team management structure where the captain (your direct PackageReference) brings in a specialist coach, who in turn brings their own assistant coaches (transitive dependencies) without the captain hiring each assistant individually, the way referencing Serilog.AspNetCore transitively pulls in Serilog itself.
dotnet add package Serilog.AspNetCore --version 8.0.1
dotnet restore
dotnet list package --include-transitive
<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
</ItemGroup>
Central Package Management and Lock Files
In a solution with many projects, Central Package Management (CPM) lets you move all Version attributes into a single Directory.Packages.props file at the solution root, with each .csproj declaring only <PackageReference Include="..." /> without a version — MSBuild resolves the version centrally, so upgrading a package solution-wide is a one-line change instead of hunting through dozens of .csproj files. For reproducible builds, a packages.lock.json file (enabled via <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>) pins the exact resolved graph, including transitive versions, so restore produces identical results on every machine and in CI until the lock file is deliberately updated.
Cricket analogy: This is like a franchise setting one central salary cap policy for the whole organization instead of each age-group team negotiating separately, so a policy change at the top (Directory.Packages.props) updates every team at once, the way CPM updates a version across every project from one file.
Run 'dotnet list package --outdated' periodically to see which of your direct dependencies have newer versions available, and 'dotnet list package --vulnerable' to check for known security advisories reported against your restored packages — both read from the same restore metadata NuGet already produced.
Floating versions like Version="8.*" or Version="[8.0.0,)" make builds non-reproducible: the exact resolved version can differ between your machine and CI depending on what was published to the feed that day. Pin exact versions, or better, commit a packages.lock.json so restores are deterministic everywhere.
- NuGet packages (.nupkg files) bundle assemblies and metadata, fetched from feeds like nuget.org and cached in a shared global-packages folder.
- PackageReference elements declare direct dependencies; NuGet resolves the full transitive dependency graph automatically.
- When versions conflict, NuGet's 'nearest wins' algorithm picks a resolved version, which can silently affect transitive packages.
- Central Package Management (Directory.Packages.props) centralizes version numbers for an entire solution in one file.
- packages.lock.json pins the exact resolved dependency graph for reproducible restores across machines and CI.
- dotnet list package --outdated and --vulnerable surface upgrade and security information from existing restore metadata.
- Avoid floating version ranges in production projects; they undermine reproducible builds.
Practice what you learned
1. Where does NuGet cache downloaded packages so multiple projects can share them?
2. If your project references Serilog.AspNetCore, why does Serilog itself end up in your dependency graph without a direct PackageReference?
3. What problem does Central Package Management (Directory.Packages.props) solve?
4. What does a packages.lock.json file guarantee?
5. Why is a floating version like Version="8.*" risky in a production project?
Was this page helpful?
You May Also Like
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics