🪟 Windows TippsMicrosoft to Hold Surface and Windows Event on October 7(16.09.2026 um 18:25 Uhr)
🪟 Windows TippsNissan bringt seinen Verkaufsschlager Kicks nach Europa(16.09.2026 um 16:34 Uhr)
🪟 Windows ServerBrowser: Firefox 156 bekommt Werbeeinblendungen - Golem.de(16.09.2026 um 17:14 Uhr)
🪟 Windows TippsMicrosoft to Hold Surface and Windows Event on October 7(16.09.2026 um 18:25 Uhr)
🪟 Windows TippsNissan bringt seinen Verkaufsschlager Kicks nach Europa(16.09.2026 um 16:34 Uhr)
🪟 Windows ServerBrowser: Firefox 156 bekommt Werbeeinblendungen - Golem.de(16.09.2026 um 17:14 Uhr)

🔧 Programmierung 🕛 vor 2 Jahren 5 Min Lesezeit
0

Merging Startup.cs and Program.cs in .NET 8: A Simplified Approach

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

As .NET evolves, so does the way we structure our applications. One notable change introduced in recent versions of .NET is the ability to merge Startup.cs and Program.cs into a single file. This approach streamlines the setup process, making it more cohesive and manageable. This article will discuss the rationale behind merging these files, walk through the process, and highlight potential advantages and pitfalls.






Why Merge Startup.cs and Program.cs?



Okay, first let me try to find some advantages and also why it can be a bad idea.






Advantages




  1. Simplified Structure: By consolidating Startup.cs and Program.cs, you create a single entry point for application configuration. This can make the codebase more straightforward to navigate and understand. Updates to configuration or middleware can be made in one file rather than spread across multiple files, reducing the likelihood of inconsistencies and errors.


  2. Improved Testability: With all configurations in one place, writing integration tests becomes simpler. Conditions and configurations are centralized, making it easier to mock dependencies and test different scenarios.







Potential Pitfalls




  1. Complexity in Large Applications: For very large applications, having all configurations in one file might become unwieldy. It's essential to balance simplicity with readability.


  2. Migration Challenges: If you're transitioning an existing application, merging these files might introduce bugs if not done carefully. A rollback could be a nightmare (speaking from experience!).







The Old Way: Separate Startup.cs and Program.cs






Original Program.cs






CODE
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
using Microsoft.Extensions.Logging.ApplicationInsights;
using System.Diagnostics;

public class Program
{
public static void Main(string[] args)
{
try
{
Debug.WriteLine("Configure infrastructure...");
BuildHost(args).Run();
}
catch (Exception ex)
{
Debug.WriteLine($"Infrastructure configuration failed: {ex}");
}
}

public static IHost BuildHost(string[] args)
{
// Configuration and host building logic
}
}









Original Startup.cs






CODE
using Microsoft.AspNetCore.Http.Features;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.FeatureManagement;
using System.Diagnostics;

public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
{
Configuration = configuration;
WebHostEnvironment = webHostEnvironment;
}

public IConfiguration Configuration { get; }
public IWebHostEnvironment WebHostEnvironment { get; }

// Methods for configuring services and middleware
}









The New Combined Mode






Combined Program.cs






CODE
using Microsoft.AspNetCore.Http.Features;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.ApplicationInsights;
using Microsoft.FeatureManagement;
using Newtonsoft.Json.Converters;
using System.Diagnostics;

var builder = WebApplication.CreateBuilder(args);

// Configuration setup
// Using builder.Configuration to setup configuration sources
builder.Configuration.AddAzureAppConfiguration(options =>
{
options.UseFeatureFlags(o =>
{
o.Label = "InstanceName"; // Replace with your instance name
o.CacheExpirationInterval = TimeSpan.FromMinutes(10);
});
options.ConfigureKeyVault(o =>
{
o.SetCredential(new DefaultAzureCredential()); // Replace with your Azure credential
o.SetSecretRefreshInterval(TimeSpan.FromMinutes(30));
});
options.Connect("YourAppConfigurationEndpoint", new DefaultAzureCredential()) // Replace with your endpoint and credential
.ConfigureRefresh(o =>
{
o.Register("Settings:Sentinel", refreshAll: true)
.SetCacheExpiration(TimeSpan.FromMinutes(10));
})
.Select(KeyFilter.Any, LabelFilter.Null)
.Select(KeyFilter.Any, labelFilter: "InstanceName"); // Replace with your instance name
});

if (builder.Environment.IsDevelopment())
{
builder.Configuration.AddJsonFile("appsettings.json", optional: true);
builder.Configuration.AddUserSecrets<Program>();
}

builder.Configuration.AddEnvironmentVariables();

// Logging setup
// Using builder.Logging to setup logging providers
builder.Logging.ClearProviders(); // Clear default providers
builder.Logging.AddConsole(); // Add console logging
builder.Logging.AddDebug(); // Add debug logging
builder.Logging.AddAzureWebAppDiagnostics(); // Add Azure diagnostics

if (!builder.Environment.IsDevelopment() && Environment.GetEnvironmentVariable("AUTOMATED_TESTING") is null)
{
builder.Logging.AddApplicationInsights(config =>
{
config.ConnectionString = builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"];
config.DisableTelemetry = false;
}, options => options.IncludeScopes = false);
}

// Services setup
var services = builder.Services;
services.AddControllers().AddNewtonsoftJson(opt => opt.SerializerSettings.Converters.Add(new StringEnumConverter()));
services.AddDbContext<YourDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
services.AddFeatureManagement();
services.AddAzureAppConfiguration();
// Register other services as needed

// Middleware setup
var app = builder.Build();

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app.Run();

// Utility methods for retrieving services
private static T GetService<T>(IServiceCollection services)
{
ServiceProvider serviceProvider = services.BuildServiceProvider();
return serviceProvider.GetService<T>() ?? throw new Exception($"Could not find service {typeof(T)}");
}

private static T GetService<T>(IApplicationBuilder app)
{
return app.ApplicationServices.GetService<T>() ?? throw new Exception($"Could not find service {typeof(T)}");
}

private static void DebugWrite(string message)
{
Console.WriteLine(message);
Debug.WriteLine(message);
}









Key Points in the Combined File





  • Configuration: Configuration sources are added using builder.Configuration. This includes Azure App Configuration, JSON files, user secrets, and environment variables.


  • Logging: Logging is set up using builder.Logging with different providers for console, debug, and Application Insights. The builder.Logging API simplifies logging configuration by providing a centralized way to add and configure logging providers.


  • Services: All service configurations, including custom services, middleware, and feature management, are consolidated. Using builder.Services makes it straightforward to register services with the dependency injection container.


  • Middleware: Middleware components are configured in one place, improving readability and maintainability. The app.UseRouting(), app.UseAuthentication(), and app.UseAuthorization() methods set up the middleware pipeline.






Our Experience and story



In our project, we have more than 100 active production instances, each with unique configuration and settings.



We faced numerous conditions for integration tests, such as checking Environment.GetEnvironmentVariable("AUTOMATED_TESTING") or custom feature flag conditions based on license.



All those conditions determine whether the application should use a different database or configure other testing-specific settings. And managing these conditions across multiple files was a pain in the a.



Since merging Startup.cs and Program.cs, we have gained a much nicer overview and more control over our application. The centralized configuration has made it significantly easier to maintain and extend our application, particularly when writing and running integration tests and switching custom features.






Conclusion



Merging Startup.cs and Program.cs can streamline your .NET applications, making them easier to test and maintain. However, be cautious during the transition to avoid introducing bugs. Start by merging the files as they are before making any improvements. This way, if something goes wrong, you'll have an easier time debugging (trust me, it happened to me...).



By following the steps and best practices outlined in this article, you can take advantage of the modern .NET hosting model and simplify your application's setup.

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Microsoft to Hold Surface and Windows Event on October 7
1 Quelle
Thrustmaster's new flight stick is a heavy and authentic A-10C HOTAS replica for PC simulator fans who crave digital dogfights
1 Quelle
Nissan bringt seinen Verkaufsschlager Kicks nach Europa
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Merging Startup.cs and Program.cs in .NET 8: A Simplified Approach

Thematisch verwandte Begriffe: Merging, Startupcs, Programcs, Simplified · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...