using Autofac.Extensions.DependencyInjection; using AutoMapper; using back.Domain; using back.Infrastructure; using MCVIngenieros.Healthchecks; using MediatR.Extensions.FluentValidation.AspNetCore; using Microsoft.EntityFrameworkCore; using OpenTelemetry.Logs; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using Scalar.AspNetCore; using Serilog; namespace back; public class Program { public static void Main(string[] args) { var configFiles = Path.Combine(AppContext.BaseDirectory, "configs"); if (!Directory.Exists(configFiles)) { Directory.CreateDirectory(configFiles); } var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"; var configurationBuilder = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{environment}.json", optional: false, reloadOnChange: true); var configs = Directory.GetFiles(configFiles, "*.json", SearchOption.AllDirectories); foreach (var config in configs) { configurationBuilder.AddJsonFile(config, optional: true, reloadOnChange: true); } var configuration = configurationBuilder.Build(); Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .MinimumLevel.Verbose() .Enrich.FromLogContext() .CreateLogger(); try { var builder = WebApplication.CreateBuilder(args); builder.Configuration.AddConfiguration(configuration); builder.Host.UseSerilog(); builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); builder.Services.AddMediatR(cfg => { cfg.RegisterServicesFromAssembly(typeof(Program).Assembly); }); builder.Services.AddFluentValidation([typeof(Program).Assembly]); builder.Services.AddAutoMapper(opts => { opts.AddProfile(); opts.AllowNullCollections = true; opts.AllowNullDestinationValues = true; opts.DestinationMemberNamingConvention = new PascalCaseNamingConvention(); }); builder.Services.AddHealthChecksSupport().DiscoverHealthChecks(); builder.Services.AddLogging(); builder.Logging.AddOpenTelemetry(options => { options .SetResourceBuilder( ResourceBuilder.CreateDefault() .AddService(AppDomain.CurrentDomain.FriendlyName)) .AddConsoleExporter(); }); builder.Services.AddOpenTelemetry() .ConfigureResource(resource => resource.AddService(AppDomain.CurrentDomain.FriendlyName)) .WithTracing(tracing => tracing .AddAspNetCoreInstrumentation() .AddConsoleExporter()) .WithMetrics(metrics => metrics .AddAspNetCoreInstrumentation() .AddConsoleExporter()); builder.Services.AddDataProtection(); builder.Services.AddCors(options => { options.AddDefaultPolicy(policy => { policy .WithOrigins(builder.Configuration.GetSection("AllowedHosts").Get() ?? []) .SetIsOriginAllowedToAllowWildcardSubdomains() .SetPreflightMaxAge(TimeSpan.FromMinutes(10)) .AllowCredentials() .AllowAnyHeader() .AllowAnyMethod(); }); }); builder.Services.AddHttpContextAccessor(); builder.Services.AddAntiforgery(options => { options.HeaderName = "X-XSRF-TOKEN"; }); builder.Services.AddDbContext(opts => { var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); opts.UseSqlite(connectionString); }); builder.Services.AddControllers(options => { options.Filters.Add(new Microsoft.AspNetCore.Mvc.RequireHttpsAttribute()); }); // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.MapOpenApi(); app.MapScalarApiReference("/api-docs", opt => { opt.WithTitle("My API Documentation"); }); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); } catch (Exception ex) { Log.Fatal(ex, "Application start-up failed"); } finally { Log.CloseAndFlush(); } } }