.NET 10VSAAugust 2026 · 7 min read

.NET 10 Source Code Tour: From Program.cs to Vertical Slices

TL;DR

In this tour, one request travels from Program.cs through dependency injection into a vertical slice handler. The slice builds the command, resolves a scoped DbContext, and calls SaveChanges — and the whole feature lives in a single folder.

.NET 10 Source Code can feel overwhelming until you follow one request from the moment the application starts to the moment a database row is written. This tour does exactly that. We will walk through a real codebase together — starting at Program.cs, passing through dependency injection and EF Core, and ending inside a vertical slice — so the structure stops being abstract and becomes something you can navigate on your own.

The Starting Point of Every .NET 10 Source Code Tour: Program.cs

Top-level statements mean a .NET 10 application begins at the first line of Program.cs. The file is built around two bookends: builder.Build() finishes the service configuration, and app.Run() starts the request pipeline. Between them, services are registered above the line and middleware is configured below it.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<AppDbContext>();
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<Program>());
builder.Services.AddRazorPages();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.MapRazorPages();
app.MapBlazorHub();

app.Run();

Everything above builder.Build() declares what the application can do; everything between the build and app.Run() decides how requests are handled. In .NET 10 source code written this way, the entire startup contract is visible on one screen, and that makes Program.cs the natural first stop of any tour.

How Dependency Injection Carries the Request Forward

When a request arrives, the framework resolves services from the container that Program.cs configured. The DbContext is registered as scoped, which means each request gets its own instance — a decision that matters because EF Core's change tracker is not thread-safe and should never outlive a single unit of work. MediatR, meanwhile, scans the whole assembly for handlers, so features can be added without touching the container again.

The resolver does the plumbing silently: a Blazor page asks for a mediator, the mediator asks for a handler, and the handler asks for a DbContext. Because every type is registered exactly once in Program.cs, following a request means following these constructor dependencies, and nothing is ever constructed by hand.

From the Slice to the Database: EF Core in the Handler

Now the request reaches the vertical slice. A slice is a small, self-contained feature — one command, one handler, one validator. The handler below updates a customer: it finds the entity, applies the changes, and commits them. The DbContext is injected through the constructor, so the handler never worries about connection lifecycle.

public class UpdateCustomerHandler(AppDbContext db)
    : IRequestHandler<UpdateCustomerCommand>
{
    public async Task Handle(UpdateCustomerCommand cmd, CancellationToken ct)
    {
        var customer = await db.Customers.FindAsync(cmd.Id, ct)
            ?? throw new KeyNotFoundException();
        customer.Name = cmd.Name;
        customer.Email = cmd.Email;
        await db.SaveChangesAsync(ct);
    }
}

Three lines carry the entire business action: locate the aggregate, mutate it, and persist it. Everything else — routing, validation, logging — is handled by MediatR pipelines or the framework itself, which is why the handler stays this small in real .NET 10 source code.

Where the Vertical Slices Live in .NET 10 Source Code

In the codebase we are touring, slices live under a Features/ folder, one subfolder per business operation. The shape is consistent across the whole application, which is what makes it so easy to read once you have seen one slice.

  • Features/Orders/CreateOrder/ — command, handler, and validator for creating orders.
  • Features/Customers/UpdateCustomer/ — the update slice shown above.
  • Features/Reports/ — query-only slices with no command, just a request and a handler.
  • Features/Shared/ — DTOs and abstractions reused across slices.

Because each folder is independent, features can be added, tested, and removed without disturbing their neighbours. This is the payoff of vertical slice organization: the folder structure of the project mirrors the mental model of the business.

A Complete Request, Step by Step

Here is the whole journey in six steps:

  • The user clicks a button on a Blazor page.
  • The page sends a command through the IMediator interface.
  • MediatR runs validation and logging pipelines around the handler.
  • The handler resolves the scoped AppDbContext from dependency injection.
  • EF Core applies the changes and SaveChanges commits the transaction.
  • The page refreshes and the UI reflects the new state.

That single chain — page, mediator, pipeline, handler, DbContext — is the backbone of a Blazor application built on vertical slices. Once you can trace it, you can trace every feature in .NET 10 source code that follows the same pattern.

Key Takeaways

  • Program.cs is the map: registrations above builder.Build, middleware below.
  • Dependency injection resolves every service automatically; follow constructor parameters.
  • EF Core handlers stay small because pipelines and the framework handle the rest.
  • Vertical slices live one folder per feature under Features/.
  • The page-to-handler-to-DbContext chain is the backbone of every feature.

FAQ

Why does the tour start at Program.cs and not at the page?

Because Program.cs defines every service the pages depend on. Without it you meet dependencies in random order; with it you already know where everything comes from before you read a single feature.

Are all .NET 10 source code projects organized into vertical slices?

No, but the tour technique works everywhere. Find the composition root, then trace a request; the slices are just the destination where this tour happens to end.

What is the point of the Features/Shared/ folder?

It holds DTOs and abstractions that several slices reuse. Keeping shared code in one place prevents duplication while preserving the independence of each slice.

Where can I find .NET 10 source code organized exactly like this tour?

Every Indotalent product ships its full .NET 10 source code at $21 each, with the exact folder structure walked through above.

Ready to tour a real codebase yourself?

Every Indotalent product is a complete .NET 10 application with full source code — $21 each. Follow the same journey from Program.cs to slices.

Explore Products