DEV Community

Ellie
Ellie

Posted on

The Two Halves of Program.cs in .NET

If you've recently jumped into .NET 6 or newer, the first file you see might be Program.cs which looks very different. The old Startup.cs file is gone, and everything is in one, minimal file.

It might look confusing, but this new Program.cs is really just a file split into two distinct jobs.

  1. The "Builder" Phase: Setting up all your tools and services.
  2. The "Pipeline" Phase: Defining the steps to handle a web request.

Let's break it down.

Part 1: The "Builder" Phase (The Setup)

Every new .NET web app starts with this line:

var builder = WebApplication.CreateBuilder(args);
Enter fullscreen mode Exit fullscreen mode

Builder is like a setup-kit. Before you can do anything, you need to "prepare" the application. This is where you setup all the services, tools, and configurations needed to run your application.

This is the phase where you register things. You'll see code that uses builder.Services:

// Example: Adding the tools for controllers
builder.Services.AddControllers();

// Example: Adding a custom tool (service) you built
// This is "Dependency Injection"
builder.Services.AddScoped<IMyService, MyService>();

// Example: Adding configuration from appsettings.json
builder.Configuration.AddJsonFile("appsettings.json");
Enter fullscreen mode Exit fullscreen mode

This part isn't running your website yet. It's just you, gathering all your tools (like registering services) and reading the details (like loading configuration).

Once you've registered all your services, you "build" the app:

var app = builder.Build();
Enter fullscreen mode Exit fullscreen mode

This line is the transition. It takes all the services and configurations you defined and bundles them into an actual application, which we call app.

That's it for Part 1. Setup is complete.

Part 2: The "Pipeline" Phase (The Recipe)

Now that we have our app, we need to tell it what to do when it receives a request from a user's browser.

This is done by creating a "middleware pipeline."

Middleware is just a piece of code that a request passes through. You chain these pieces of code together, one after another, to create a "pipeline."

The most important thing to remember here is that the order matters. A lot.

The request goes through the pipeline from top to bottom. Then, the response goes back up through the pipeline in reverse order.

Think of it like this:
Request -> Middleware 1 -> Middleware 2 -> Your Code -> Middleware 2 -> Middleware 1 -> Response

This setup is powerful. It lets you do things before your main code runs (like checking if the user is authenticated) and things after your code runs (like logging the response).

You define this pipeline using app.Use...() methods:

// This is the pipeline
// We are "using" different pieces of middleware

// 1. First, if we're not in development, handle errors
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts(); // Add security headers
}

// 2. Redirect HTTP requests to HTTPS
app.UseHttpsRedirection();

// 3. Find out which "endpoint" (like a method) to run
app.UseRouting();

// 4. Check if the user is allowed to be here
app.UseAuthorization();

// 5. Finally, map the request to our actual code
app.MapGet("/", () => "Hello World!");

// This is the very last step.
// This line actually starts the server and listens for requests.
app.Run();

Enter fullscreen mode Exit fullscreen mode

In the example above:

A request comes in.

  • It's checked for HTTPS (UseHttpsRedirection).
  • It's checked for which endpoint it matches (UseRouting).
  • It's checked for permissions (UseAuthorization).
  • Finally, it hits our endpoint (MapGet) and "Hello World!" is returned.

That "Hello World!" string then travels back up the pipeline, and the final response is sent to the user.

Conclusion

So, next time you look at a Program.cs file, don't get overwhelmed. Just split it in your mind:

  • The Top Half (builder): This is just setup. We're registering our services (Dependency Injection).
  • The Bottom Half (app): This is the recipe. We're defining the step-by-step pipeline to handle requests.

Simple, right?

Top comments (0)