Exemplo n.º 1
0
        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;
        }
Exemplo n.º 2
0
        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;
        }