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; }