skipnothing/.NET Platform
UNIT 05

Build & Distribution

Restore, metaproj, source mapping: the supply chain

`dotnet build` is the visible step. Restore is the one that decides which DLLs even exist for the compiler to see. This unit traces that supply chain: which command triggers which target, which feed answers, which asset crosses the project boundary.

Loading…
BUILDS ON
TOPICS
#23

Restore Pipeline

Split a single `dotnet build` into its restore-then-compile halves, follow the two restore phases (an MSBuild collection pass running CollectPackageReferences into the dgspec, then a NuGet resolver writing obj/project.assets.json), and show why deleting obj/ still restores fast while a matching dgspec hash skips restore entirely.

Run `dotnet build` and the compiler is the second thing that happens, not the first. Before one line compiles, a separate step has already walked your packages, picked exact builds, and written them to disk.

14 min
#24

MSBuild Targets & Hooks

Trace which MSBuild targets fire under project restore versus solution restore, watch a BeforeTargets="Restore" hook silently no-op when a solution synthesizes its .sln.metaproj, and bind restore-time logic to CollectPackageReferences so it fires on every entry point.

Add one line to your build to pin a package version and run `dotnet restore` on the project: it works. Run the same command on the solution and it quietly does nothing, no error, no pin.

16 min
#25

Asset Flow & References

Map an `IncludeAssets`/`ExcludeAssets`/`PrivateAssets` combination to which asset streams your build consumes versus which flow to a downstream consumer, and decide when a build-time-only package (protoc tools, analyzers, source generators) earns `PrivateAssets=all`.

You add one `<PackageReference>` line and a package's whole `lib/`, `build/`, and `analyzers/` folder wires itself into your project. Some of that should reach whoever consumes your library later, most of it should not.

12 min
#26

Sources, Feeds & Mapping

Race two feeds for the same package id and watch order get ignored, compose a repo nuget.config whose <clear /> stops it inheriting machine-level sources, and pin each id to a feed with packageSourceMapping so a public impostor of a private package is never queried.

You list two servers in a config file, run `dotnet restore`, and whichever answers first hands over the package. Swap their order in the file and the result can change on its own, because the order was never a ranking.

14 min
All units