public static IServiceCollection AddSciter <TPrimaryHost>(
            this IServiceCollection services,
            Action <SciterHostOptions> hostOptions     = null,
            Action <SciterWindowOptions> windowOptions = null)
            where TPrimaryHost : SciterHost
        {
            services
            //.AddSingleton<HostEventHandlerRegistry>((provider) => HostEventHandlerRegistry.Instance)
            .AddSingleton <IHostWindowResolver, HostWindowResolver>()
            .AddSingleton <INamedBehaviorResolver, NamedBehaviorResolver>()
            .AddHostWindow <TPrimaryHost>()
            .AddHostEventHandler <TPrimaryHost>();

            services.AddTransient <TPrimaryHost>(
                provider =>
            {
                using var scope           = provider.CreateScope();
                var scopedServiceProvider = scope.ServiceProvider;

                var sciterHostOptions   = new SciterHostOptions(scopedServiceProvider);
                var sciterWindowOptions = new SciterWindowOptions(scopedServiceProvider);
                hostOptions?.Invoke(sciterHostOptions);

                /*THost result;
                 *
                 * if (typeof(THost).Implements<SciterArchiveHost>())
                 * {
                 *  var archiveAttribute = typeof(THost)
                 *      .GetCustomAttributes<SciterHostArchiveAttribute>(inherit: true).FirstOrDefault();
                 *
                 *  result = ActivatorUtilities.CreateInstance<THost>(provider);
                 *
                 *  //Archive = new SciterArchive(archiveAttribute?.BaseUrl ?? SciterArchive.DEFAULT_ARCHIVE_URI)
                 *  //    .Open();
                 * }
                 * else
                 * {
                 *  result = ActivatorUtilities.CreateInstance<THost>(provider);
                 * }*/

                if (sciterHostOptions.ArchiveUri != null)
                {
                }

                var result = ActivatorUtilities.CreateInstance <TPrimaryHost>(scopedServiceProvider);

                var archives = scopedServiceProvider.GetServices <LazySciterArchive>();

                foreach (var archive in archives)
                {
                    archive.Open();
                    result.AttachedArchives.TryAdd(archive.Uri.Scheme, archive);

                    if (archive.InitScripts?.Any() != true)
                    {
                        continue;
                    }

                    foreach (var initScript in archive.InitScripts)
                    {
                        var byteArray   = Encoding.UTF8.GetBytes($"include \"{initScript}\";");
                        var pinnedArray = GCHandle.Alloc(byteArray, GCHandleType.Pinned);
                        var pointer     = pinnedArray.AddrOfPinnedObject();
                        Sciter.SciterApi.SciterSetOption(IntPtr.Zero, SciterXDef.SCITER_RT_OPTIONS.SCITER_SET_INIT_SCRIPT,
                                                         pointer);
                        pinnedArray.Free();
                    }
                }


                var namedBehaviorResolver = scopedServiceProvider.GetService <INamedBehaviorResolver>();

                if (namedBehaviorResolver != null)
                {
                    result.SetBehaviorResolver(namedBehaviorResolver);
                }

                var hostWindowResolver = scopedServiceProvider.GetService <IHostWindowResolver>();

                var sciterWindow = hostWindowResolver?.GetWindow(typeof(TPrimaryHost));

                if (sciterWindow != null && windowOptions != null)
                {
                    windowOptions?.Invoke(sciterWindowOptions);

                    if (!string.IsNullOrWhiteSpace(sciterWindowOptions?.Title))
                    {
                        sciterWindow.SetTitle(sciterWindowOptions.Title);
                    }

                    if (sciterWindowOptions.Height.HasValue && sciterWindowOptions.Width.HasValue)
                    {
                        //sciterWindow.SetDimensions();
                    }

                    switch (sciterWindowOptions.Position)
                    {
                    case SciterWindowPosition.CenterScreen:
                        sciterWindow.CenterWindow();
                        break;

                    case SciterWindowPosition.Custom:
                        break;

                    case SciterWindowPosition.Default:
                    default:
                        break;
                        ;
                    }
                }

                result?.SetupWindow(sciterWindow);
                //result?.Window.TryLoadPage(uri: new Uri("this://app/index.html"));

                HostEventHandlerRegistry.Instance
                .TryGetValue(typeof(TPrimaryHost), out var hostEventHandlerType);

                if (hostEventHandlerType != null && scopedServiceProvider
                    .GetService(hostEventHandlerType) is SciterEventHandler hostEventHandler)
                {
                    result?.AttachEventHandler(hostEventHandler);
                }

                //Must load the `Home Page` after setting up the Window and attaching the Hosts' EventHandler
                if (sciterHostOptions.HomePageUri != null)
                {
                    var homePageUri = sciterHostOptions.HomePageUri;

                    if (result is SciterArchiveHost && !sciterHostOptions.HomePageUri.IsAbsoluteUri && sciterHostOptions.ArchiveUri != null)
                    {
                        homePageUri = new Uri(sciterHostOptions.ArchiveUri, sciterHostOptions.HomePageUri);
                    }

                    result?.Window.TryLoadPage(uri: homePageUri);
                }

                result
                ?.OnCreated
                ?.Invoke(result, new HostCreatedEventArgs(sciterWindow));

                return(result);
            });

            services.AddTransient <SciterHost, TPrimaryHost>(provider => provider.GetRequiredService <TPrimaryHost>());

            services.AddSingleton <SciterApplication>(provider =>
                                                      ActivatorUtilities.CreateInstance <SciterApplication>(provider, provider.GetRequiredService <TPrimaryHost>()));

            return(services);
        }
 private static object CreateInstance(this IServiceProvider provider, Type type, params object[] arguments)
 {
     return(ActivatorUtilities.CreateInstance(provider, type, arguments));
 }
Esempio n. 3
0
        public static IServiceCollection AddTriggeredDbContextFactory <TContext>(this IServiceCollection serviceCollection, Action <DbContextOptionsBuilder>?optionsAction = null, ServiceLifetime lifetime = ServiceLifetime.Singleton)
            where TContext : DbContext
        {
            serviceCollection.AddDbContextFactory <TContext>(options => {
                optionsAction?.Invoke(options);
                options.UseTriggers();
            }, lifetime);

            var serviceDescriptor = serviceCollection.FirstOrDefault(x => x.ServiceType == typeof(IDbContextFactory <TContext>));


            if (serviceDescriptor?.ImplementationType != null)
            {
                var triggeredFactoryType = typeof(TriggeredDbContextFactory <,>).MakeGenericType(typeof(TContext), serviceDescriptor.ImplementationType);

                serviceCollection.TryAdd(ServiceDescriptor.Describe(
                                             serviceType: serviceDescriptor.ImplementationType,
                                             implementationType: serviceDescriptor.ImplementationType,
                                             lifetime: serviceDescriptor.Lifetime
                                             ));

                serviceCollection.Replace(ServiceDescriptor.Describe(
                                              serviceType: typeof(IDbContextFactory <TContext>),
                                              implementationFactory: serviceProvider => ActivatorUtilities.CreateInstance(serviceProvider, triggeredFactoryType, serviceProvider.GetService(serviceDescriptor.ImplementationType), serviceProvider),
                                              lifetime: ServiceLifetime.Scoped
                                              ));
            }

            return(serviceCollection);
        }
 public static T Create <T>(this Plugin plugin, IServiceProvider serviceProvider) where T : class
 {
     return(ActivatorUtilities.CreateInstance(serviceProvider, plugin) as T);
 }
 public static object Create(this Plugin plugin, IServiceProvider serviceProvider)
 {
     return(ActivatorUtilities.CreateInstance(serviceProvider, plugin));
 }
        /// <summary>
        /// Adds essential DotVVM services to the specified <see cref="IServiceCollection" />.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
        /// <param name="allowDebugServices">If the vs-diagnostics services should be registered</param>
        public static IServiceCollection RegisterDotVVMServices(IServiceCollection services, bool allowDebugServices = true)
        {
            services.AddOptions();

            if (allowDebugServices)
            {
                services.AddDiagnosticServices();
            }

            services.TryAddSingleton <IDotvvmViewBuilder, DefaultDotvvmViewBuilder>();
            services.TryAddSingleton <IViewModelSerializer, DefaultViewModelSerializer>();
            services.TryAddSingleton <IViewModelLoader, DefaultViewModelLoader>();
            services.TryAddSingleton <IViewModelValidationMetadataProvider, AttributeViewModelValidationMetadataProvider>();
            services.TryAddSingleton <IValidationRuleTranslator, ViewModelValidationRuleTranslator>();
            services.TryAddSingleton <IViewModelValidator, ViewModelValidator>();
            services.TryAddSingleton <IViewModelSerializationMapper, ViewModelSerializationMapper>();
            services.TryAddSingleton <IViewModelParameterBinder, AttributeViewModelParameterBinder>();
            services.TryAddSingleton <IOutputRenderer, DefaultOutputRenderer>();
            services.TryAddSingleton <IDotvvmPresenter, DotvvmPresenter>();
            services.TryAddSingleton <IMarkupFileLoader, AggregateMarkupFileLoader>();
            services.TryAddSingleton <IControlBuilderFactory, DefaultControlBuilderFactory>();
            services.TryAddSingleton <IControlResolver, DefaultControlResolver>();
            services.TryAddSingleton <IControlTreeResolver, DefaultControlTreeResolver>();
            services.TryAddSingleton <IAbstractTreeBuilder, ResolvedTreeBuilder>();
            services.TryAddSingleton <Func <ControlUsageValidationVisitor> >(s => () => ActivatorUtilities.CreateInstance <ControlUsageValidationVisitor>(s));
            services.TryAddSingleton <IViewCompiler, DefaultViewCompiler>();
            services.TryAddSingleton <IBindingCompiler, BindingCompiler>();
            services.TryAddSingleton <IBindingExpressionBuilder, BindingExpressionBuilder>();
            services.TryAddSingleton <BindingCompilationService, BindingCompilationService>();
            services.TryAddSingleton <DataPager.CommonBindings>();
            services.TryAddSingleton <IControlUsageValidator, DefaultControlUsageValidator>();
            services.TryAddSingleton <ILocalResourceUrlManager, LocalResourceUrlManager>();
            services.TryAddSingleton <IResourceHashService, DefaultResourceHashService>();
            services.TryAddSingleton <StaticCommandBindingCompiler, StaticCommandBindingCompiler>();
            services.TryAddSingleton <JavascriptTranslator, JavascriptTranslator>();
            services.TryAddSingleton <IHttpRedirectService, DefaultHttpRedirectService>();

            services.TryAddScoped <AggregateRequestTracer, AggregateRequestTracer>();
            services.TryAddScoped <ResourceManager, ResourceManager>();
            services.TryAddSingleton(s => DotvvmConfiguration.CreateDefault(s));
            services.TryAddSingleton(s => s.GetRequiredService <DotvvmConfiguration>().Markup);
            services.TryAddSingleton(s => s.GetRequiredService <DotvvmConfiguration>().Resources);
            services.TryAddSingleton(s => s.GetRequiredService <DotvvmConfiguration>().RouteTable);
            services.TryAddSingleton(s => s.GetRequiredService <DotvvmConfiguration>().Runtime);
            services.TryAddSingleton(s => s.GetRequiredService <DotvvmConfiguration>().Security);
            services.TryAddSingleton(s => s.GetRequiredService <DotvvmConfiguration>().Styles);

            services.ConfigureWithServices <BindingCompilationOptions>((o, s) => {
                o.TransformerClasses.Add(ActivatorUtilities.CreateInstance <BindingPropertyResolvers>(s));
            });

            services.ConfigureWithServices <ViewCompilerConfiguration>((o, s) => {
                var requiredResourceControl = s.GetRequiredService <IControlResolver>().ResolveControl(new ResolvedTypeDescriptor(typeof(RequiredResource)));
                o.TreeVisitors.Add(() => new BindingRequiredResourceVisitor((ControlResolverMetadata)requiredResourceControl));
                o.TreeVisitors.Add(() => ActivatorUtilities.CreateInstance <StylingVisitor>(s));
                o.TreeVisitors.Add(() => ActivatorUtilities.CreateInstance <DataContextPropertyAssigningVisitor>(s));
                o.TreeVisitors.Add(() => new LifecycleRequirementsAssigningVisitor());
            });

            return(services);
        }
 /// <summary>
 /// Instantiates a new object of the specified type, but with support for constructor injection.
 /// </summary>
 public static TResult CreateInstance <TResult>(this IServiceProvider provider, Type type) where TResult : class
 {
     return((TResult)ActivatorUtilities.CreateInstance(provider, type));
 }
        /// <summary>
        /// Adds a <see cref="IMessageHandler{TMessage,TMessageContext}" /> implementation to process the messages from an Azure Service Bus.
        /// resources.
        /// </summary>
        /// <typeparam name="TMessageHandler">The type of the implementation.</typeparam>
        /// <typeparam name="TMessage">The type of the message that the message handler will process.</typeparam>
        /// <typeparam name="TMessageContext">The type of the context in which the message handler will process the message.</typeparam>
        /// <param name="services">The collection of services to use in the application.</param>
        /// <param name="messageContextFilter">The function that determines if the message handler should handle the message based on the context.</param>
        /// <param name="messageBodyFilter">The filter to restrict the message processing based on the incoming message body.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="services"/>, <paramref name="messageContextFilter"/>, or <paramref name="messageBodyFilter"/> is <c>null</c>.</exception>
        public static MessageHandlerCollection WithMessageHandler <TMessageHandler, TMessage, TMessageContext>(
            this MessageHandlerCollection services,
            Func <TMessageContext, bool> messageContextFilter,
            Func <TMessage, bool> messageBodyFilter)
            where TMessageHandler : class, IMessageHandler <TMessage, TMessageContext>
            where TMessage : class
            where TMessageContext : MessageContext
        {
            Guard.NotNull(services, nameof(services), "Requires a set of services to add the message handler");
            Guard.NotNull(messageContextFilter, nameof(messageContextFilter), "Requires a filter to restrict the message processing within a certain message context");
            Guard.NotNull(messageBodyFilter, nameof(messageBodyFilter), "Requires a filter to restrict the message processing based on the incoming message body");

            return(WithMessageHandler <TMessageHandler, TMessage, TMessageContext>(
                       services, messageContextFilter, messageBodyFilter, serviceProvider => ActivatorUtilities.CreateInstance <TMessageHandler>(serviceProvider)));
        }
 /// <summary>
 /// Adds and configures a IMultiTenantStrategy to the applicationusing default dependency injection.
 /// </summary>
 /// <param name="lifetime">The service lifetime.</param>
 /// <param name="parameters">a paramter list for any constructor paramaters not covered by dependency injection.</param>
 /// <returns>The same MultiTenantBuilder passed into the method.</returns>
 public FinbuckeMultiTenantBuilder WithStrategy <T>(ServiceLifetime lifetime, params object[] parameters) where T : IMultiTenantStrategy
 => WithStrategy(lifetime, sp => ActivatorUtilities.CreateInstance <T>(sp, parameters));
 /// <summary>
 /// Adds and configures a IMultiTenantStore to the application using default dependency injection.
 /// </summary>>
 /// <param name="lifetime">The service lifetime.</param>
 /// <param name="parameters">a paramter list for any constructor paramaters not covered by dependency injection.</param>
 /// <returns>The same MultiTenantBuilder passed into the method.</returns>
 public FinbuckleMultiTenantBuilder <TTenantInfo> WithStore <TStore>(ServiceLifetime lifetime, params object[] parameters)
     where TStore : IMultiTenantStore <TTenantInfo>
 => WithStore <TStore>(lifetime, sp => ActivatorUtilities.CreateInstance <TStore>(sp, parameters));
 //https://stackoverflow.com/questions/53884417/net-core-di-ways-of-passing-parameters-to-constructor
 public static T ResolveWith <T>(this IServiceProvider provider, params object[] parameters) where T : class =>
 ActivatorUtilities.CreateInstance <T>(provider, parameters);
Esempio n. 12
0
        public static IServiceCollection AddFluentMigratorCore(
            [NotNull] this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            services
            // Add support for options
            .AddOptions()

            // Add loggins support
            .AddLogging()

            // The default assembly loader factory
            .AddSingleton <AssemblyLoaderFactory>()

            // Assembly loader engines
            .AddSingleton <IAssemblyLoadEngine, AssemblyNameLoadEngine>()
            .AddSingleton <IAssemblyLoadEngine, AssemblyFileLoadEngine>()

            // Defines the assemblies that are used to find migrations, profiles, maintenance code, etc...
            .AddSingleton <IAssemblySource, AssemblySource>()

            // Configure the loader for migrations that should be executed during maintenance steps
            .AddSingleton <IMaintenanceLoader, MaintenanceLoader>()

            // Add the default embedded resource provider
            .AddSingleton <IEmbeddedResourceProvider>(sp => new DefaultEmbeddedResourceProvider(sp.GetRequiredService <IAssemblySource>().Assemblies))

            // The default set of conventions to be applied to migration expressions
            .AddSingleton <IConventionSet, DefaultConventionSet>()

            // Configure the runner conventions
            .AddSingleton <IMigrationRunnerConventionsAccessor, AssemblySourceMigrationRunnerConventionsAccessor>()
            .AddSingleton(sp => sp.GetRequiredService <IMigrationRunnerConventionsAccessor>().MigrationRunnerConventions)

            // The IStopWatch implementation used to show query timing
            .AddSingleton <IStopWatch, StopWatch>()

            // Source for migrations
#pragma warning disable 618
            .AddScoped <IMigrationSource, MigrationSource>()
            .AddScoped(
                sp => sp.GetRequiredService <IMigrationSource>() as IFilteringMigrationSource
                ?? ActivatorUtilities.CreateInstance <MigrationSource>(sp))
#pragma warning restore 618

            // Source for profiles
            .AddScoped <IProfileSource, ProfileSource>()

            // Configure the accessor for the version table metadata
            .AddScoped <IVersionTableMetaDataAccessor, AssemblySourceVersionTableMetaDataAccessor>()

            // Configure the default version table metadata
            .AddScoped(sp => sp.GetRequiredService <IVersionTableMetaDataAccessor>().VersionTableMetaData ?? ActivatorUtilities.CreateInstance <DefaultVersionTableMetaData>(sp))

            // Configure the migration information loader
            .AddScoped <IMigrationInformationLoader, DefaultMigrationInformationLoader>()

            // Provide a way to get the migration generator selected by its options
            .AddScoped <IGeneratorAccessor, SelectingGeneratorAccessor>()

            // Provide a way to get the migration accessor selected by its options
            .AddScoped <IProcessorAccessor, SelectingProcessorAccessor>()

            // IQuerySchema is the base interface for the IMigrationProcessor
            .AddScoped <IQuerySchema>(sp => sp.GetRequiredService <IProcessorAccessor>().Processor)

            // The profile loader needed by the migration runner
            .AddScoped <IProfileLoader, ProfileLoader>()

            // Some services especially for the migration runner implementation
            .AddScoped <IMigrationExpressionValidator, DefaultMigrationExpressionValidator>()
            .AddScoped <MigrationValidator>()
            .AddScoped <MigrationScopeHandler>()

            // The connection string readers
#if NETFRAMEWORK
            .AddScoped <INetConfigManager, NetConfigManager>()
#pragma warning disable 612
            .AddScoped <IConnectionStringReader, AppConfigConnectionStringReader>()
#pragma warning restore 612
#endif

            .AddScoped <IConnectionStringReader, ConfigurationConnectionStringReader>()

            // The connection string accessor that evaluates the readers
            .AddScoped <IConnectionStringAccessor, ConnectionStringAccessor>()

            .AddScoped <IVersionLoader>(
                sp =>
            {
                var options       = sp.GetRequiredService <IOptions <RunnerOptions> >();
                var connAccessor  = sp.GetRequiredService <IConnectionStringAccessor>();
                var hasConnection = !string.IsNullOrEmpty(connAccessor.ConnectionString);
                if (options.Value.NoConnection || !hasConnection)
                {
                    return(ActivatorUtilities.CreateInstance <ConnectionlessVersionLoader>(sp));
                }

                return(ActivatorUtilities.CreateInstance <VersionLoader>(sp));
            })

            // Configure the runner
            .AddScoped <IMigrationRunner, MigrationRunner>()

            // Configure the task executor
            .AddScoped <TaskExecutor>()

            // Migration context
            .AddTransient <IMigrationContext>(
                sp =>
            {
                var querySchema = sp.GetRequiredService <IQuerySchema>();
                var options     = sp.GetRequiredService <IOptions <RunnerOptions> >();
                var connectionStringAccessor = sp.GetRequiredService <IConnectionStringAccessor>();
                var connectionString         = connectionStringAccessor.ConnectionString;
#pragma warning disable 612
                var appContext = options.Value.ApplicationContext;
#pragma warning restore 612
                return(new MigrationContext(querySchema, sp, appContext, connectionString));
            });

            return(services);
        }
Esempio n. 13
0
 public ConnectionlessProcessorAccessor(IServiceProvider serviceProvider)
 {
     Processor = ActivatorUtilities.CreateInstance <ConnectionlessProcessor>(serviceProvider);
 }
Esempio n. 14
0
        /// <summary>
        /// Adds a <see cref="IMessageHandler{TMessage, TMessageContext}" /> implementation to process the messages from an Azure Service Bus.
        /// resources.
        /// </summary>
        /// <typeparam name="TMessageHandler">The type of the implementation.</typeparam>
        /// <typeparam name="TMessage">The type of the message that the message handler will process.</typeparam>
        /// <typeparam name="TMessageContext">The type of the context in which the message handler will process the message.</typeparam>
        /// <param name="services">The collection of services to use in the application.</param>
        /// <param name="messageContextFilter">The function that determines if the message handler should handle the message based on the context.</param>
        /// <param name="messageBodySerializerImplementationFactory">The function that creates the <see cref="IMessageBodySerializer"/> implementation.</param>
        public static MessageHandlerCollection WithMessageHandler <TMessageHandler, TMessage, TMessageContext>(
            this MessageHandlerCollection services,
            Func <TMessageContext, bool> messageContextFilter,
            Func <IServiceProvider, IMessageBodySerializer> messageBodySerializerImplementationFactory)
            where TMessageHandler : class, IMessageHandler <TMessage, TMessageContext>
            where TMessage : class
            where TMessageContext : MessageContext
        {
            Guard.NotNull(services, nameof(services), "Requires a set of services to add the message handler");
            Guard.NotNull(messageContextFilter, nameof(messageContextFilter), "Requires a filter to restrict the message processing within a certain message context");
            Guard.NotNull(messageBodySerializerImplementationFactory, nameof(messageBodySerializerImplementationFactory), "Requires a function to create an custom message body serializer to deserialize the incoming message for the message handler");

            return(services.WithMessageHandler <TMessageHandler, TMessage, TMessageContext>(
                       messageContextFilter, messageBodySerializerImplementationFactory, serviceProvider => ActivatorUtilities.CreateInstance <TMessageHandler>(serviceProvider)));
        }
Esempio n. 15
0
        public static IServiceCollection AddHealthChecksUI(this IServiceCollection services, string databaseName = "healthchecksdb", Action <Settings> setupSettings = null)
        {
            var configuration = services.BuildServiceProvider()
                                .GetService <IConfiguration>();

            services
            .AddOptions()
            .Configure <Settings>(settings =>
            {
                configuration.BindUISettings(settings);
                setupSettings?.Invoke(settings);
            })
            .Configure <KubernetesDiscoverySettings>(settings =>
            {
                configuration.Bind(Keys.HEALTHCHECKSUI_KUBERNETES_DISCOVERY_SETTING_KEY, settings);
            })
            .Configure <DockerDiscoverySettings>(settings =>
            {
                configuration.Bind(Keys.HEALTHCHECKSUI_DOCKER_DISCOVERY_SETTING_KEY, settings);
            })
            .AddSingleton <IHostedService, HealthCheckCollectorHostedService>()
            .AddScoped <IHealthCheckFailureNotifier, WebHookFailureNotifier>()
            .AddScoped <IHealthCheckReportCollector, HealthCheckReportCollector>()
            .AddHttpClient(Keys.HEALTH_CHECK_HTTP_CLIENT_NAME)
            .ConfigurePrimaryHttpMessageHandler(sp =>
            {
                var settings = sp.GetService <IOptions <Settings> >();
                return(settings.Value.ApiEndpointHttpHandler?.Invoke(sp) ?? new HttpClientHandler());
            }).Services
            .AddHttpClient(Keys.HEALTH_CHECK_WEBHOOK_HTTP_CLIENT_NAME)
            .ConfigurePrimaryHttpMessageHandler(sp =>
            {
                var settings = sp.GetService <IOptions <Settings> >();
                return(settings.Value.WebHooksEndpointHttpHandler?.Invoke(sp) ?? new HttpClientHandler());
            });

            var healthCheckSettings = services.BuildServiceProvider()
                                      .GetService <IOptions <Settings> >()
                                      .Value ?? new Settings();

            var kubernetesDiscoverySettings = services.BuildServiceProvider()
                                              .GetService <IOptions <KubernetesDiscoverySettings> >()
                                              .Value ?? new KubernetesDiscoverySettings();

            var dockerDiscoverySettings = services.BuildServiceProvider()
                                          .GetService <IOptions <DockerDiscoverySettings> >()
                                          .Value ?? new DockerDiscoverySettings();

            services.AddDbContext <HealthChecksDb>(db =>
            {
                var connectionString = healthCheckSettings.HealthCheckDatabaseConnectionString;
                if (string.IsNullOrWhiteSpace(connectionString))
                {
                    var contentRoot  = configuration[HostDefaults.ContentRootKey];
                    var path         = Path.Combine(contentRoot, databaseName);
                    connectionString = $"Data Source={path}";
                }
                else
                {
                    connectionString = Environment.ExpandEnvironmentVariables(connectionString);
                }
                db.UseSqlite(connectionString);
            });

            if (kubernetesDiscoverySettings.Enabled)
            {
                services.AddSingleton(kubernetesDiscoverySettings)
                .AddHostedService <KubernetesDiscoveryHostedService>()
                .AddHttpClient(Keys.K8S_DISCOVERY_HTTP_CLIENT_NAME, (provider, client) => client.ConfigureKubernetesClient(provider))
                .ConfigureKubernetesMessageHandler()
                .Services
                .AddHttpClient(Keys.K8S_CLUSTER_SERVICE_HTTP_CLIENT_NAME);
            }

            if (dockerDiscoverySettings.Enabled)
            {
                services.AddHostedService <DockerDiscoveryHostedService>()
                .AddScoped <IDiscoveryRegistryService, DiscoveryRegistryService>()
                .AddSingleton <IDockerDiscoveryService>(x =>
                {
                    var config = x.GetRequiredService <IOptions <DockerDiscoverySettings> >().Value;

                    var uri         = new Uri(config.Endpoint);
                    var labelPrefix = $"{config.ServicesLabelPrefix}.";

                    return(ActivatorUtilities.CreateInstance <DockerDiscoveryService>(x, uri, labelPrefix));
                })
                .AddHttpClient(Keys.DISCOVERY_SERVICE_HTTP_CLIENT_NAME);
            }

            var serviceProvider = services.BuildServiceProvider();

            CreateDatabase(serviceProvider).Wait();

            return(services);
        }
 /// <summary>
 /// Enables multiple existing health checks to be evaluated only when a specific condition occurs,
 /// that is described by a type implementing <see cref="IConditionalHealthCheckPolicy"/>
 /// and which will be executed on every health check request.
 /// </summary>
 /// <remarks>
 /// The instance of this type is created with every request and its dependencies are resolved by <see cref="IServiceProvider"/>.
 /// If the constructor has more arguments then these can be passed via the <paramref name="conditionalHealthCheckPolicyCtorArgs"/> parameter.
 /// </remarks>
 /// <typeparam name="T">The type implementing <see cref="IConditionalHealthCheckPolicy"/>.</typeparam>
 /// <param name="builder">The builder used to register health checks.</param>
 /// <param name="names">
 /// The list of names of the existing health checks, ie. "Redis", "redis", "S3", "My Health Check".
 /// The health checks must be previously registered using the other <see cref="IHealthChecksBuilder" /> extensions, like AddRedis, AddRabbitMQ, AddCheck, etc.
 /// You can use the static <see cref="Registrations"/> class that contains a list of well-known names,
 /// otherwise specify the name of the previously added health check.
 /// </param>
 /// <param name="conditionalHealthCheckPolicyCtorArgs"></param>
 /// <param name="options">A list of options to override the default behavior. See <see cref="ConditionalHealthCheckOptions"/> for extra details.</param>
 /// <returns>The same builder used to register health checks.</returns>
 /// <exception cref="ArgumentException">When the name of the health check is not provided, ie. is null or is an empty string.</exception>
 /// <exception cref="InvalidOperationException">When the health check identified by the previously given name is not registered yet.</exception>
 public static IHealthChecksBuilder CheckOnlyWhen <T>(this IHealthChecksBuilder builder,
                                                      string[] names,
                                                      ConditionalHealthCheckOptions?options = null,
                                                      params object[] conditionalHealthCheckPolicyCtorArgs)
     where T : IConditionalHealthCheckPolicy
 => builder.CheckOnlyWhen(names, (sp, _, __) => Task.FromResult(ActivatorUtilities.CreateInstance <T>(sp, conditionalHealthCheckPolicyCtorArgs)), options);