public static IHostBuilder CreateHostBuilder <T>(MainOptions options) where T : class => Host.CreateDefaultBuilder(options.CommandLineArguments) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup <T>() .UseConfiguration(GetConfigurationBuilder(options.EnvironmentVariableKey)) .UseSerilog(); });
/// <summary> /// The program's main start/entry point. Hold on to your butts .... here we go! /// </summary> /// <typeparam name="T">Startup class type.</typeparam> /// <param name="args">Optional command line arguments.</param> /// <returns>Task of this Main application run.</returns> public static async Task Main <T>(string[] args) where T : class { var options = new MainOptions { CommandLineArguments = args }; await Main <T>(options); }
/// <summary> /// The program's main start/entry point. Hold on to your butts .... here we go! /// </summary> /// <typeparam name="T">Startup class type.</typeparam> /// <param name="options">Options to help setup/configure your program.</param> /// <returns>Task of this Main application run.</returns> public static async Task Main <T>(MainOptions options) where T : class { try { if (options is null) { throw new ArgumentNullException(nameof(options)); } // Before we do _ANYTHING_ we need to have a logger so we can start // seeing what is going on ... good or bad. Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(GetConfigurationBuilder(options.EnvironmentVariableKey)) .Enrich.FromLogContext() .CreateLogger(); // Display any (optional) initial banner / opening text to define the start of this application now starting. if (!string.IsNullOrWhiteSpace(options.FirstLoggingInformationMessage)) { Log.Information(options.FirstLoggingInformationMessage); } if (options.LogAssemblyInformation) { var assembly = typeof(T).Assembly; var assemblyDate = string.IsNullOrWhiteSpace(assembly.Location) ? "-- unknown --" : File.GetLastWriteTime(assembly.Location).ToString("u"); var assemblyInfo = $"Name: {assembly.GetName().Name} | Version: {assembly.GetName().Version} | Date: {assemblyDate}"; Log.Information(assemblyInfo); } await CreateHostBuilder <T>(options.CommandLineArguments).Build() .RunAsync(); } catch (Exception exception) { const string errorMessage = "Something seriously unexpected has occurred while preparing the Host. Sadness :~("; // We might NOT have created a logger ... because we might be _trying_ to create the logger but // we have some bad setup-configuration-data and boom!!! No logger successfully setup/created. // So, if we do have a logger created, then use it. if (Log.Logger is Logger) { // TODO: Add metrics (like Application Insights?) to log telemetry failures. Log.Logger.Fatal(exception, errorMessage); } else { // Nope - failed to create a logger and we have a serious error. So lets // just fall back to the Console and _hope_ someone can read/access that. Console.WriteLine(Explosion); Console.WriteLine(errorMessage); Console.WriteLine(); Console.WriteLine(); Console.WriteLine($"Error: {exception.Message}"); Console.WriteLine(); } } finally { var shutdownMessage = string.IsNullOrWhiteSpace(options.LastLoggingInformationMessage) ? "Application has now shutdown." : options.LastLoggingInformationMessage; // Again: did we successfully create a logger? if (Log.Logger is Logger) { Log.Information(shutdownMessage); // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux) Log.CloseAndFlush(); } else { Console.WriteLine(shutdownMessage); } } }