RSS Amplifier

The .NET Saturday Newsletter · Aug 1, 2026

Before You Start a .NET Web API, Add These 3 Files

0
Sign in to vote or save

Muhammad Waseem · The .NET Saturday Newsletter

Before You Start a .NET Web API, Add These 3 Files
Before You Start a .NET Web API, Add These 3 Files

Sponsor this newsletter

Most developers create a new Web API and immediately start writing controllers, entities, and endpoints.

That works until the project grows.

Then formatting becomes inconsistent, NuGet versions start drifting, and your AI coding assistant keeps making decisions that do not match your architecture.

Before writing the first endpoint, I recommend setting up these three things:

  1. .editorconfig

  2. Central NuGet Package Management

  3. CLAUDE.md

They take a few minutes to configure and save hours of cleanup later.

The .editorconfig file defines how code should look across the entire solution.

It can control:

  • Indentation and spacing

  • File-scoped namespaces

  • Brace placement

  • Use of var

  • Naming conventions

  • Unused imports

  • Code-analysis severity

  • Special rules for migrations and tests

For example:

root = true
[*.cs]
indent_size = 4
indent_style = space
csharp_style_namespace_declarations = file_scoped
dotnet_style_readonly_field = true
dotnet_diagnostic.IDE0005.severity = warning

Without an.editorconfig, every developer’s IDE can format code differently.

One person uses var. Another writes explicit types. One removes braces. Another adds them back.

Soon, your pull requests contain more formatting changes than actual business logic.

A shared .editorconfig gives the whole team one coding standard. Your existing configuration can also enforce interface naming, PascalCase members, analyzer rules, migration exclusions, and test-specific exceptions.

The goal is simple:

Stop debating formatting during code reviews.

Let the configuration handle it.

In a solution with multiple projects, package versions can quickly become inconsistent.

Your API project might use one version of Entity Framework Core while your Persistence project uses another.

That is how strange restore errors and dependency conflicts begin.

Create a Directory.Packages.props file at the solution root:

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
    <CentralPackageTransitivePinningEnabled>
      true
    </CentralPackageTransitivePinningEnabled>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion
      Include="Microsoft.EntityFrameworkCore"
      Version="9.0.4" />
    <PackageVersion
      Include="Npgsql.EntityFrameworkCore.PostgreSQL"
      Version="9.0.4" />
    <PackageVersion
      Include="Serilog.AspNetCore"
      Version="9.0.0" />
    <PackageVersion
      Include="OpenTelemetry.Extensions.Hosting"
      Version="1.15.3" />
  </ItemGroup>
</Project>

Your individual project files can then reference packages without specifying versions:

<ItemGroup>
  <PackageReference Include="Microsoft.EntityFrameworkCore" />
  <PackageReference Include="Serilog.AspNetCore" />
</ItemGroup>

Now every project gets its package versions from one place.

This gives you:

  • One place to update packages

  • Consistent versions across projects

  • Easier security upgrades

  • Fewer dependency conflicts

  • Cleaner .csproj files

CentralPackageTransitivePinningEnabled also lets NuGet promote and pin a transitive dependency when a centrally defined version needs to be enforced.

You can combine this with a Directory.Build.props file for solution-wide settings:

<Project>
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <AnalysisLevel>latest</AnalysisLevel>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
  </PropertyGroup>
</Project>

A good rule is:

Package versions belong in Directory.Packages.props. Shared build rules belong in Directory.Build.props.

Also, do not copy a hundred packages into a new project just because you might need them someday.

Add packages when the project actually needs them. NuGet packages are dependencies, not Pokémon.

If you use Claude Code or another AI coding assistant, create a CLAUDE.md file at the repository root.

This file acts as the project’s instruction manual.

It should explain:

  • What the application does

  • Which technologies it uses

  • How the solution is structured

  • Where new features should go

  • Which commands should be used

  • How migrations should be created

  • How tests should be organized

  • Which architectural rules must never be broken

  • Which actions require explicit approval

For example:

# Project Guidelines
This project is a .NET 9 Web API using Clean Architecture,
EF Core, PostgreSQL, Wolverine, and OpenTelemetry.
## Architecture
- Domain contains entities and domain events.
- Application contains business logic and abstractions.
- Persistence contains EF Core and service implementations.
- Infrastructure contains external integrations.
- API contains controllers and dependency injection.
## Important Rules
- Never use DbContext directly in the Application layer.
- Never create EF Core migrations manually.
- Every new feature must include tests.
- Never run git push unless explicitly requested.
- Use fluent LINQ syntax instead of query syntax.

Without project instructions, the AI has to guess.

It may place database code inside the Application layer, create migrations manually, skip tests, introduce a different folder structure, or push code when you only asked it to make a local change.

A detailed CLAUDE.md can document commands, architecture, feature workflows, security rules, testing expectations, deployment constraints, and even instructions such as never running git push without permission.

The AI does not know your unwritten rules.

Write them down once, and you will not need to repeat them in every prompt.

When starting a new Web API, I now follow this order:

  1. Create the solution and projects.

  2. Add .editorconfig.

  3. Add Directory.Build.props.

  4. Add Directory.Packages.props.

  5. Add CLAUDE.md.

  6. Configure analyzers and warnings.

  7. Run dotnet build.

  8. Only then start building features.

These files are not exciting.

They will not appear in your product demo, and your client will never ask about them.

But they create the foundation for consistent code, predictable builds, controlled dependencies, and safer AI-assisted development.

A clean project does not begin with the first controller.

It begins with the rules that every controller must follow.

  1. Boost your .NET skills by subscribing to my YouTube Channel

  2. Promote yourself to 10,000+ subscribers by sponsoring this newsletter

Read the original on mwaseemzakir.substack.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.