intermediate15 min

.NET Project Structure and the dotnet CLI

The .csproj file, NuGet packages, and the everyday dotnet CLI commands.

What you'll learn

  • Explain what a `.csproj` file declares for a project
  • Describe what a NuGet package is and how a project references one
  • Use `dotnet new`, `dotnet build`, `dotnet run`, and `dotnet test` appropriately

Explanation

A .NET project is defined by a .csproj file -- an XML file naming the target framework (e.g. net8.0), the output type (an executable Exe or a reusable Library), and any package references. Modern SDK-style .csproj files are deliberately short: unlike some older project formats, they do not need to individually list every .cs source file -- any .cs file anywhere in the project's folder (and subfolders, by default) is automatically included in the build. This means adding a second source file alongside Program.cs (like a small helper class) just works, with nothing to edit in the .csproj itself.

A NuGet package is a versioned, shareable unit of .NET code that you add to a project as a <PackageReference> -- the .csproj records which packages and versions a project depends on, and the dotnet CLI restores them before building.

The everyday dotnet CLI commands: dotnet new console -o myapp scaffolds a new console project into a folder; dotnet build compiles the project without running it; dotnet run compiles (if needed) and immediately runs it; dotnet test runs a project's automated tests (typically written with a framework like xUnit or MSTest, referenced as NuGet packages in a separate test project).

A single .csproj can build together as many .cs files as you put in its folder tree -- a project's identity comes entirely from its one .csproj file, not from any declaration inside the .cs files themselves.

Guided lab

Predict: A two-file console project

C#Not executed
This lab does not run in your browser or on VisaSparkSchools's servers. Read the code, predict what it does, then reveal the real expected output.

This shows two .cs files from the same project (comments mark the file boundary) -- both are compiled together automatically since SDK-style projects include every .cs file in the folder. Predict what `dotnet run` prints.

// file: MathUtil.cs
public static class MathUtil
{
    public static int Add(int a, int b)
    {
        return a + b;
    }
}

// file: Program.cs
using System;

Console.WriteLine($"2 + 3 = {MathUtil.Add(2, 3)}");
Console.WriteLine("Run with: dotnet run");

Stuck? Get a hint.

Common mistakes

  • Expecting to manually list every `.cs` file inside the `.csproj`, like some older project formats required -- modern SDK-style projects include source files automatically.
  • Confusing `dotnet build` (compiles only) with `dotnet run` (compiles, if needed, and immediately executes).
  • Assuming a NuGet package reference is optional metadata -- without it correctly declared in the `.csproj`, `dotnet restore`/`dotnet build` can't resolve that dependency at all.

Knowledge check

Knowledge check

1. Do modern SDK-style `.csproj` files need to individually list every `.cs` source file?
2. What does `dotnet build` do that `dotnet run` also does, but `dotnet run` does one additional thing?
3. What is a NuGet package?

Takeaway

A `.csproj` names a project's target framework, output type, and package references -- modern SDK-style projects auto-include source files, so there's rarely anything to edit there when you just add another `.cs` file; `dotnet run` builds and executes in one step.

Summary

.csproj declares a project's framework, output type, and NuGet package references (with source files included automatically); the dotnet CLI's new/build/run/test commands scaffold, compile, execute, and test a project.

References

Your notes

Notes save automatically.

Finished this lesson?

Mark it complete to track your progress and schedule a future review.