Namespaces, projects and NuGet

C# · Essentials · 10 min

Real programs span many files and depend on packages; this is how C# keeps that organized.

A namespace groups related types and avoids name clashes: System.Collections.Generic.List<T>. Declare one at the top of a file with a file-scoped namespace: namespace Shop.Orders;. Folder structure conventionally mirrors namespaces.

Use types from another namespace with a using directive: using System.Text;. Variants:

  • global using System.Text.Json; applies to every file in the project (often in a GlobalUsings.cs).
  • Implicit usings (<ImplicitUsings>enable</ImplicitUsings>) import System, System.IO, System.Linq, System.Collections.Generic, System.Threading.Tasks and more automatically.
  • using static System.Math; lets you call Sqrt(2) without the class name.
  • using Json = System.Text.Json.JsonSerializer; creates an alias.

A project (.csproj) compiles into one assembly (a .dll or executable). A solution (.sln or the newer .slnx) groups projects. Projects reference each other with dotnet add reference ../Lib/Lib.csproj.

Third-party libraries come from NuGet: dotnet add package Serilog adds a <PackageReference Include="Serilog" Version="..." /> to the csproj, and dotnet restore (run automatically by build) downloads it. Central package management (Directory.Packages.props) keeps versions consistent across many projects.

internal types are visible only within their assembly, so you can keep implementation details out of a library's public API.

Example

<!-- Shop.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
    <!-- added by: dotnet add package Humanizer -->
    <PackageReference Include="Humanizer" Version="2.14.1" />
    <!-- added by: dotnet add reference ../Shop.Core/Shop.Core.csproj -->
    <ProjectReference Include="../Shop.Core/Shop.Core.csproj" />
  </ItemGroup>
</Project>

Remember

  • File-scoped namespace Foo.Bar; at the top of each file
  • Implicit and global usings remove repetitive imports
  • One .csproj compiles to one assembly
  • dotnet add package adds a NuGet PackageReference

Check yourself

  1. What does internal mean on a class?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/namespaces