protected BaseApplication( Func <IHostBuilder, IHostBuilder>?configureHost = null, Action <IServiceCollection>?configureServices = null, Action <HostBuilderContext, ILoggingBuilder>?configureLogging = null, string?alreadyRunningMessage = null, int waitAfterOldInstanceKillMilliseconds = 0, NewInstanceHandling newInstanceHandling = NewInstanceHandling.Restart, CultureInfo?startupCulture = null) { var cultureManager = new CultureManager(); var applicationTerminator = new ApplicationTerminator(); var assemblyInfoProvider = new AssemblyInfoProvider(new EntryAssemblyProvider(), new SpecialPathsProvider()); _applicationBootstrapper = new ApplicationStartupBootstrapper( cultureManager, applicationTerminator, ShowMessage, CreateMutex, RegisterDependencies, assemblyInfoProvider, configureHost, configureServices, configureLogging, alreadyRunningMessage, waitAfterOldInstanceKillMilliseconds, newInstanceHandling, startupCulture); DispatcherUnhandledException += App_DispatcherUnhandledException; }
public WepApiLauncher( Action <ContainerBuilder, IConfiguration>?registerDependencies = null, Func <IHostBuilder, IHostBuilder>?configureHost = null, Action <IServiceCollection>?configureServices = null, Action <HostBuilderContext, ILoggingBuilder>?configureLogging = null, string?alreadyRunningMessage = null, int waitAfterOldInstanceKillMilliseconds = 0, NewInstanceHandling newInstanceHandling = NewInstanceHandling.AllowMultiple, CultureInfo?startupCulture = null, Assembly?webApiAssembly = null, IReadOnlyCollection <Assembly>?additionalXmlCommentsAssemblies = null) { IConfiguration?configuration = null; var cultureManager = new ConsoleCultureManager(); var applicationTerminator = new ConsoleApplicationTerminator(); _assemblyInfoProvider = new AssemblyInfoProvider(new EntryAssemblyProvider(), new SpecialPathsProvider()); webApiAssembly ??= Assembly.GetCallingAssembly(); var baseDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule?.FileName) ?? throw new InvalidOperationException("Cannot get base directory"); Directory.SetCurrentDirectory(baseDirectory); _applicationBootstrapper = new ApplicationStartupBootstrapper( cultureManager, applicationTerminator, message => { }, CreateMutex, containerBuilder => registerDependencies?.Invoke(containerBuilder, configuration ?? throw new InvalidOperationException("Configuration was not initialized")), _assemblyInfoProvider, hostBuilder => { configureHost?.Invoke(hostBuilder); hostBuilder.UseConsoleLifetime(); return(ApiHostingHelper.RegisterWebApiHost(hostBuilder, baseDirectory: baseDirectory, applicationKey: webApiAssembly.GetName().Name)); }, services => { // Build the intermediate service provider var sp = services.BuildServiceProvider(); configuration = sp.GetRequiredService <IConfiguration>(); var appSettings = configuration.GetSection("AppSettings"); var appName = appSettings[AppSettingsConstants.AppNameKey]; var appVersion = appSettings[AppSettingsConstants.AppVersionKey]; ApiHostingHelper.RegisterServices( services, webApiAssembly, configureMvc: mvcBuilder => mvcBuilder.AddJsonOptions( options => { options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)); }), configureSwagger: swaggerGenOptions => { swaggerGenOptions.SwaggerDoc("v1", new OpenApiInfo { Title = appName, Version = appVersion }); var xmlDocAssemblies = new List <Assembly> { webApiAssembly }; if (additionalXmlCommentsAssemblies != null) { xmlDocAssemblies.AddRange(additionalXmlCommentsAssemblies); } foreach (var xmlFilePath in xmlDocAssemblies.Select(assembly => assembly.GetName().Name + ".xml") .Select(xmlFileName => Path.Combine(baseDirectory, xmlFileName)) .Where(File.Exists)) { swaggerGenOptions.IncludeXmlComments(xmlFilePath); } // If there are two similar routes - this will fix the collision by choosing the first one swaggerGenOptions.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); }) .Configure <ConsoleLifetimeOptions>(options => options.SuppressStatusMessages = true) .AddHttpContextAccessor(); configureServices?.Invoke(services); }, (hostBuilderContext, loggingBuilder) => { SetupLogging(baseDirectory, hostBuilderContext.HostingEnvironment.EnvironmentName, LogEventLevel.Debug); loggingBuilder.AddSerilog(); configureLogging?.Invoke(hostBuilderContext, loggingBuilder); }, alreadyRunningMessage, waitAfterOldInstanceKillMilliseconds, newInstanceHandling, startupCulture, baseDirectory); _applicationBootstrapper.BeforeStart(); Configuration = configuration ?? throw new InvalidOperationException("Configuration was not initialized"); }
public ApplicationStartupBootstrapper( ICultureManager cultureManager, IApplicationTerminator applicationTerminator, Action <Message> showMessage, Func <Mutex>?createMutex, Action <ContainerBuilder> registerDependencies, IAssemblyInfoProvider assemblyInfoProvider, Func <IHostBuilder, IHostBuilder>?configureHost = null, Action <IServiceCollection>?configureServices = null, Action <HostBuilderContext, ILoggingBuilder>?configureLogging = null, string?alreadyRunningMessage = null, int waitAfterOldInstanceKillMilliseconds = 0, NewInstanceHandling newInstanceHandling = NewInstanceHandling.Restart, CultureInfo?startupCulture = null, string?baseDirectory = null) { // This is used for logs - every log will have a CorrelationId; Trace.CorrelationManager.ActivityId = Guid.NewGuid(); _ = registerDependencies ?? throw new ArgumentNullException(nameof(registerDependencies)); _assemblyInfoProvider = assemblyInfoProvider ?? throw new ArgumentNullException(nameof(assemblyInfoProvider)); _alreadyRunningMessage = alreadyRunningMessage ?? $"{assemblyInfoProvider.Product} is already launched"; _waitAfterOldInstanceKillMilliseconds = waitAfterOldInstanceKillMilliseconds; _newInstanceHandling = newInstanceHandling; ShowMessage = showMessage ?? throw new ArgumentNullException(nameof(cultureManager)); CultureManager = cultureManager ?? throw new ArgumentNullException(nameof(cultureManager)); _applicationTerminator = applicationTerminator ?? throw new ArgumentNullException(nameof(applicationTerminator)); baseDirectory ??= Path.GetDirectoryName(Process.GetCurrentProcess().MainModule?.FileName) ?? throw new InvalidOperationException("Cannot get base directory"); if (_newInstanceHandling != NewInstanceHandling.AllowMultiple) { _mutex = createMutex == null?CreateCommonMutex() : createMutex(); } var hostBuilder = Host.CreateDefaultBuilder() .ConfigureServices( serviceCollection => { configureServices?.Invoke(serviceCollection); serviceCollection.AddLogging(); }) .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; var mainAppSettingsFilePath = Path.Combine(baseDirectory, "appsettings.json"); var environmentSpecificAppSettingsFilePath = Path.Combine(baseDirectory, $"appsettings.{env.EnvironmentName}.json"); if (File.Exists(mainAppSettingsFilePath)) { config.AddJsonFile(mainAppSettingsFilePath, true, true); } if (File.Exists(environmentSpecificAppSettingsFilePath)) { config.AddJsonFile(environmentSpecificAppSettingsFilePath, true, true); } }) .ConfigureLogging( (hostBuilderContext, loggingBuilder) => { configureLogging?.Invoke(hostBuilderContext, loggingBuilder); }) .UseServiceProviderFactory( new AutofacServiceProviderFactory( containerBuilder => { containerBuilder.Register(x => SynchronizationContext ?? throw new InvalidOperationException("SyncContext should not be null at the moment of registration")) .AsSelf() .SingleInstance(); containerBuilder.RegisterInstance(new MessageHub()).AsImplementedInterfaces().SingleInstance(); containerBuilder.RegisterInstance(_assemblyInfoProvider).AsImplementedInterfaces().SingleInstance(); registerDependencies(containerBuilder); })); if (configureHost != null) { hostBuilder = configureHost(hostBuilder); } _host = hostBuilder.Build(); Container = _host.Services.GetAutofacRoot(); CultureManager.ChangeCulture(startupCulture ?? Thread.CurrentThread.CurrentUICulture); Messenger = Container.Resolve <IMessageHub>(); _subscriptionTokens.Add(Messenger.Subscribe <Message>(LogAndShowMessage)); _subscriptionTokens.Add(Messenger.Subscribe <CultureInfo>(CultureManager.ChangeCulture)); _logger = Container.Resolve <ILogger <ApplicationStartupBootstrapper> >(); TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; }