ASP.NET Core Startup Class Structure Explained: A Complete Guide to dotnet/aspnetcore
The ASP.NET Core Startup class consists of three essential parts—an optional constructor for dependency injection, a ConfigureServices method to register application services with the DI container, and a Configure method to build the HTTP request pipeline.
The Startup class serves as the central entry point that wires up an application’s services and request-processing pipeline in ASP.NET Core. According to the dotnet/aspnetcore source code, this architectural pattern separates service registration (application-wide) from request pipeline configuration (per-request), making applications composable and testable. Understanding the Startup class structure is essential for configuring middleware, dependency injection, and hosting options across different deployment scenarios.
The Three Core Components of an ASP.NET Core Startup Class
Constructor Injection (Optional)
The constructor accepts injected services such as IConfiguration or IWebHostEnvironment that are needed during startup. In src/Servers/Kestrel/samples/SampleApp/Startup.cs, the host injects these dependencies before calling the configuration methods, allowing conditional logic based on configuration settings or environment name.
ConfigureServices Method
This method registers services with the built-in DI container and runs once before any requests are processed. The canonical signature is:
public void ConfigureServices(IServiceCollection services)
As shown in src/DefaultBuilder/samples/SampleApp/Startup.cs, this is where you add MVC, Entity Framework Core, authentication, and other framework services. Advanced scenarios in src/Hosting/test/testassets/IStartupInjectionAssemblyName/Startup.cs demonstrate returning a custom IServiceProvider to replace the default container.
Configure Method
This method builds the HTTP request pipeline by adding middleware and executes to process requests. The common signature accepts IApplicationBuilder and additional services:
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
The implementation in src/Servers/Kestrel/samples/SampleApp/Startup.cs demonstrates how middleware like UseClientCertBuffering() is added to the pipeline. The IApplicationBuilder supplied is backed by the built service provider, allowing middleware to request services via app.ApplicationServices.
How the Host Invokes the Startup Class
The generic host processes the Startup class through four distinct phases:
- Host creation –
HostBuilder(orWebHostBuilder) callsUseStartup<Startup>()to specify the startup type. - Instance creation – The host instantiates the Startup class, injecting any constructor parameters it can resolve from the service provider.
- Service registration –
ConfigureServicesis invoked; all services added toIServiceCollectionbecome available for constructor injection throughout the application. - Pipeline building – After the service container is built,
Configureruns. TheIApplicationBuilderis backed by the built service provider, enabling middleware to resolve dependencies.
Implementation Examples from the aspnetcore Repository
Minimal Configuration (DefaultBuilder Sample)
The minimal implementation in src/DefaultBuilder/samples/SampleApp/Startup.cs demonstrates the essential structure with empty service registration and basic request handling:
public class Startup
{
public void ConfigureServices(IServiceCollection services) { }
public void Configure(IApplicationBuilder app, IConfiguration config)
{
app.Run(async ctx =>
{
await ctx.Response.WriteAsync($"Hello from {ctx.Request.GetDisplayUrl()}\r\n");
});
}
}
MVC and Environment-Specific Middleware
This pattern from the repository demonstrates conditional middleware based on IWebHostEnvironment injection:
public class Startup
{
private readonly IWebHostEnvironment _env;
public Startup(IWebHostEnvironment env) => _env = env;
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
if (_env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Custom Host Configuration with Kestrel
The full-featured sample in src/Servers/Kestrel/samples/SampleApp/Startup.cs includes a static Main method and custom Kestrel options:
public class Startup
{
public void ConfigureServices(IServiceCollection services) { }
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
var logger = loggerFactory.CreateLogger("Default");
app.UseClientCertBuffering();
app.Run(async context =>
{
// Request handling logic
});
}
public static Task Main(string[] args)
{
var host = new HostBuilder()
.ConfigureWebHost(web =>
{
web.UseKestrel((ctx, opts) =>
{
opts.Listen(IPAddress.Loopback, 5000);
opts.ListenLocalhost(5001, l => l.UseHttps());
})
.UseStartup<Startup>();
})
.Build();
return host.RunAsync();
}
}
Additional reference implementations include HTTP/2 specific configuration in src/Servers/Kestrel/samples/Http2SampleApp/Startup.cs, IIS-integrated hosting in src/Servers/IIS/IISIntegration/samples/IISSample/Startup.cs, and MVC sandbox examples in src/Mvc/samples/MvcSandbox/Startup.cs.
Advanced Startup Patterns
Returning a Custom IServiceProvider
Advanced scenarios may replace the default dependency injection container by returning IServiceProvider from ConfigureServices. The test asset in src/Hosting/test/testassets/IStartupInjectionAssemblyName/Startup.cs demonstrates this pattern where the method signature becomes public IServiceProvider ConfigureServices(IServiceCollection services).
Configure Method Overloads
The Configure method can accept additional services directly as parameters—such as IConfiguration, ILoggerFactory, or IHostEnvironment—to avoid pulling them manually from the container. This pattern appears throughout the samples including src/Servers/Kestrel/samples/SampleApp/Startup.cs.
Summary
- The ASP.NET Core Startup class consists of three logical parts: an optional constructor for dependency injection,
ConfigureServicesfor registering application services, andConfigurefor building the middleware pipeline. ConfigureServicesruns once during application startup to populate the DI container, whileConfigureestablishes the HTTP pipeline structure that executes per request.- The dotnet/aspnetcore repository demonstrates variations ranging from minimal startups in
src/DefaultBuilder/samples/SampleApp/Startup.csto complex configurations with customMainmethods and Kestrel options insrc/Servers/Kestrel/samples/SampleApp/Startup.cs.
Frequently Asked Questions
Is the constructor required in an ASP.NET Core Startup class?
No, the constructor is optional. You only need it when your startup logic requires access to injected services like IConfiguration or IWebHostEnvironment before the configuration methods run. The host can instantiate the Startup class without a constructor if no initial dependencies are required.
What is the difference between ConfigureServices and Configure in the Startup class?
ConfigureServices registers application services with the dependency injection container and runs once at startup to build the service provider, while Configure builds the HTTP request pipeline by adding middleware and sets up the application to handle requests. The IApplicationBuilder passed to Configure is backed by the service provider built from ConfigureServices.
Can I replace the default dependency injection container in the Startup class?
Yes, ConfigureServices can return a custom IServiceProvider instead of void. This advanced pattern allows you to replace the built-in DI container with alternatives like Autofac or StructureMap, as demonstrated in test assets within the dotnet/aspnetcore repository at src/Hosting/test/testassets/IStartupInjectionAssemblyName/Startup.cs.
Where does the Configure method get its parameters from?
The host injects parameters into Configure from the service provider built after ConfigureServices runs. Common parameters include IApplicationBuilder, ILoggerFactory, IConfiguration, and IWebHostEnvironment, which are resolved automatically by the generic host without requiring manual lookup from the container.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →