100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

Project Structure and Program.cs

How a default ASP.NET Core project is laid out and how Program.cs bootstraps the host, services, and request pipeline.

FoundationsBeginner9 min readJul 10, 2026
Analogies

Project Structure and Program.cs

A freshly created ASP.NET Core project centers on a single Program.cs file that both configures services and defines the HTTP request pipeline, replacing the older split between Program.cs and Startup.cs used before .NET 6. This top-level statement style removes ceremony while keeping the same two-phase model underneath: first you register services with the dependency injection container, then you build the app and wire up middleware.

🏏

Cricket analogy: It's like a modern franchise combining the roles of coach and captain into one accountable figure who both selects the squad and sets the field, instead of splitting those decisions across two separate committees.

The Two Phases: Services and Pipeline

The first half of Program.cs uses WebApplicationBuilder to register services into the DI container, things like controllers, Entity Framework Core's DbContext, authentication schemes, and custom application services via builder.Services. Calling builder.Build() finalizes that configuration into an immutable WebApplication instance; everything after that point configures the HTTP request pipeline with middleware calls like app.UseAuthentication() and app.MapControllers().

🏏

Cricket analogy: It's like team selection happening before the toss, once the eleven is locked in, you move into match strategy, and you can't add a twelfth player mid-innings the way you can't register new services after Build().

Typical Folder Layout

A conventional ASP.NET Core web project includes a Controllers folder for MVC or API controllers, a Models folder for data and view models, a Views folder for Razor templates in MVC apps, wwwroot for static assets like CSS and JavaScript, and appsettings.json plus appsettings.{Environment}.json for configuration. Minimal API projects often collapse controllers into endpoint definitions directly in Program.cs or grouped extension methods, trading folder ceremony for conciseness on smaller services.

🏏

Cricket analogy: It's like a cricket ground's fixed zones, the pitch, the boundary rope, the pavilion, the nets, each folder in the project plays a distinct, conventional role just as each zone on the ground has its own purpose.

csharp
var builder = WebApplication.CreateBuilder(args);

// Phase 1: register services
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));
builder.Services.AddScoped<IOrderService, OrderService>();

var app = builder.Build();

// Phase 2: configure the pipeline
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Calling builder.Services.AddX() after builder.Build() has already been called will throw at runtime, the service collection becomes read-only once the WebApplication is built. All service registration must happen before Build().

  • Since .NET 6, Program.cs merges the old Startup.cs and Program.cs into one top-level-statements file.
  • WebApplicationBuilder registers services into the DI container in the first phase.
  • builder.Build() finalizes configuration into an immutable WebApplication instance.
  • The second phase configures the HTTP request pipeline using app.UseX() and app.MapX() calls.
  • Conventional folders include Controllers, Models, Views, and wwwroot for static assets.
  • Minimal API projects often skip Controllers/Views folders in favor of endpoints defined directly in Program.cs.
  • Service registration must happen before Build(); the container is locked afterward.

Practice what you learned

Was this page helpful?

Topics covered

#ASPNETCoreStudyNotes#MicrosoftTechnologies#ProjectStructureAndProgramCs#Project#Structure#Program#Two#StudyNotes#SkillVeris#ExamPrep