using BankSampahApp.Services; using BankSampahApp.Filters; using Microsoft.AspNetCore.HttpOverrides; var builder = WebApplication.CreateBuilder(args); // Configure logging dengan .NET 9 improvements builder.Logging.ClearProviders(); builder.Logging.AddConsole(); builder.Logging.AddDebug(); if (builder.Environment.IsProduction()) { var connectionString = builder.Configuration.GetConnectionString("ApplicationInsights"); if (!string.IsNullOrEmpty(connectionString)) { builder.Logging.AddApplicationInsights( configureTelemetryConfiguration: (config) => config.ConnectionString = connectionString, configureApplicationInsightsLoggerOptions: (options) => { }); } } // Add services with .NET 9 enhancements builder.Services.AddControllersWithViews(options => { // Add global filters options.Filters.Add(); }); // Register application services builder.Services.AddScoped(); builder.Services.AddScoped(); // Register new optimized services builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddScoped(); // Add HTTP client with resilience builder.Services.AddHttpClient(); // Configure forwarded headers for reverse proxy scenarios builder.Services.Configure(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; }); // Add OpenAPI support for .NET 9 if (builder.Environment.IsDevelopment()) { builder.Services.AddOpenApi(); } // Add response compression builder.Services.AddResponseCompression(options => { options.EnableForHttps = true; }); // Add response caching builder.Services.AddResponseCaching(); // Configure security headers builder.Services.AddAntiforgery(options => { options.HeaderName = "X-CSRF-TOKEN"; options.Cookie.SameSite = SameSiteMode.Strict; }); // Add memory cache builder.Services.AddMemoryCache(); var app = builder.Build(); // Configure the HTTP request pipeline with .NET 9 patterns app.UseForwardedHeaders(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // Use HSTS with proper configuration app.UseHsts(); } else { app.UseDeveloperExceptionPage(); // Add OpenAPI in development app.MapOpenApi(); } // Security headers app.Use(async (context, next) => { context.Response.Headers.Append("X-Content-Type-Options", "nosniff"); context.Response.Headers.Append("X-Frame-Options", "DENY"); context.Response.Headers.Append("X-XSS-Protection", "1; mode=block"); context.Response.Headers.Append("Referrer-Policy", "strict-origin-when-cross-origin"); if (context.Request.IsHttps) { context.Response.Headers.Append("Strict-Transport-Security", "max-age=31536000; includeSubDomains"); } await next(); }); app.UseResponseCompression(); app.UseResponseCaching(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAntiforgery(); app.UseAuthorization(); // Map routes with .NET 9 improvements app.MapControllerRoute( name: "areas", pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"); // Health check endpoint app.MapGet("/health", () => Results.Ok(new { Status = "Healthy", Timestamp = DateTime.UtcNow, Environment = app.Environment.EnvironmentName, Version = typeof(Program).Assembly.GetName().Version?.ToString() })); // Add graceful shutdown app.Lifetime.ApplicationStopping.Register(() => { app.Logger.LogInformation("Application is shutting down gracefully..."); }); app.Run();