public static IHostBuilder AddScriptHostCore()

in src/WebJobs.Script/ScriptHostBuilderExtensions.cs [172:366]


        public static IHostBuilder AddScriptHostCore(this IHostBuilder builder, ScriptApplicationHostOptions applicationHostOptions, Action<IWebJobsBuilder> configureWebJobs = null, ILoggerFactory loggerFactory = null)
        {
            var skipHostInitialization = builder.Properties.ContainsKey(ScriptConstants.SkipHostInitializationKey);

            builder.ConfigureServices((context, services) =>
            {
                services.AddSingleton<ExternalConfigurationStartupValidator>();
                services.AddSingleton<IHostedService>(s =>
                {
                    if (!skipHostInitialization)
                    {
                        var environment = s.GetService<IEnvironment>();

                        // This key will not be here if we don't have any external configuration startups registered
                        if (context.Properties.TryGetValue(ConfigurationSnapshotKey, out object originalConfigObject) &&
                            originalConfigObject is IConfigurationRoot originalConfig)
                        {
                            context.Properties.Remove(ConfigurationSnapshotKey);

                            // Validate the config for anything that needs the Scale Controller.
                            // Including Core Tools as a warning during development time.
                            if (environment.IsWindowsConsumption() ||
                                environment.IsAnyLinuxConsumption() ||
                                (environment.IsWindowsElasticPremium() && !environment.IsRuntimeScaleMonitoringEnabled()) ||
                                environment.IsCoreTools())
                            {
                                var validator = s.GetService<ExternalConfigurationStartupValidator>();
                                var logger = s.GetService<ILoggerFactory>().CreateLogger<ExternalConfigurationStartupValidator>();

                                return new ExternalConfigurationStartupValidatorService(validator, originalConfig, environment, logger);
                            }
                        }
                    }

                    return NullHostedService.Instance;
                });

                // Wire this up early so that any early worker logs are guaranteed to be flushed if any other
                // IHostedService has a slow startup.
                services.AddSingleton<IHostedService, WorkerConsoleLogService>();
            });

            builder.ConfigureWebJobs((context, webJobsBuilder) =>
            {
                // Built in binding registrations
                webJobsBuilder.AddExecutionContextBinding(o =>
                {
                    o.AppDirectory = applicationHostOptions.ScriptPath;
                })
                .AddHttp()
                .AddTimersWithStorage()
                .AddManualTrigger()
                .AddWarmup();

                var bundleManager = context.Properties.GetAndRemove<IExtensionBundleManager>(BundleManagerKey);
                webJobsBuilder.Services.AddSingleton<IExtensionBundleManager>(_ => bundleManager);

                if (!skipHostInitialization)
                {
                    var webJobsBuilderContext = new WebJobsBuilderContext
                    {
                        Configuration = context.Configuration,
                        EnvironmentName = context.HostingEnvironment.EnvironmentName,
                        ApplicationRootPath = applicationHostOptions.ScriptPath
                    };

                    // Only set our external startup if we're not suppressing host initialization
                    // as we don't want to load user assemblies otherwise.
                    var locator = context.Properties.GetAndRemove<ScriptStartupTypeLocator>(StartupTypeLocatorKey);

                    try
                    {
                        webJobsBuilder.UseExternalStartup(locator, webJobsBuilderContext, loggerFactory);
                    }
                    catch (Exception ex)
                    {
                        string appInsightsConnStr = GetConfigurationValue(EnvironmentSettingNames.AppInsightsConnectionString, context.Configuration);
                        string appInsightsAuthStr = GetConfigurationValue(EnvironmentSettingNames.AppInsightsAuthenticationString, context.Configuration);
                        RecordAndThrowExternalStartupException("Error configuring services in an external startup class.", ex, loggerFactory, appInsightsConnStr, appInsightsAuthStr);
                    }
                }

                configureWebJobs?.Invoke(webJobsBuilder);
            }, o => o.AllowPartialHostStartup = true,
            (context, webJobsConfigBuilder) =>
            {
                if (!skipHostInitialization)
                {
                    var webJobsBuilderContext = new WebJobsBuilderContext
                    {
                        Configuration = context.Configuration,
                        EnvironmentName = context.HostingEnvironment.EnvironmentName,
                        ApplicationRootPath = applicationHostOptions.ScriptPath
                    };

                    // Delay this call so we can call the customer's setup last.
                    context.Properties[DelayedConfigurationActionKey] = new Action<IWebJobsStartupTypeLocator>(locator =>
                    {
                        try
                        {
                            webJobsConfigBuilder.UseExternalConfigurationStartup(locator, webJobsBuilderContext, loggerFactory);
                        }
                        catch (Exception ex)
                        {
                            // Go directly to the environment; We have no valid configuration from the customer at this point.
                            string appInsightsConnStr = GetConfigurationValue(EnvironmentSettingNames.AppInsightsConnectionString);
                            string appInsightsAuthStr = GetConfigurationValue(EnvironmentSettingNames.AppInsightsAuthenticationString);
                            RecordAndThrowExternalStartupException("Error building configuration in an external startup class.", ex, loggerFactory, appInsightsConnStr, appInsightsAuthStr);
                        }
                    });
                }
            });

            // Script host services - these services are scoped to a host instance, and when a new host
            // is created, these services are recreated
            builder.ConfigureServices(services =>
            {
                // Core WebJobs/Script Host services
                services.AddSingleton<ScriptHost>();

                // HTTP Worker
                services.AddSingleton<IHttpWorkerProcessFactory, HttpWorkerProcessFactory>();
                services.AddSingleton<IHttpWorkerChannelFactory, HttpWorkerChannelFactory>();
                services.AddSingleton<IHttpWorkerService, DefaultHttpWorkerService>();
                // Rpc Worker
                services.AddSingleton<IJobHostRpcWorkerChannelManager, JobHostRpcWorkerChannelManager>();
                services.AddSingleton<IRpcFunctionInvocationDispatcherLoadBalancer, RpcFunctionInvocationDispatcherLoadBalancer>();

                //Worker Function Invocation dispatcher
                services.AddSingleton<IFunctionInvocationDispatcherFactory, FunctionInvocationDispatcherFactory>();
                services.AddSingleton<IScriptJobHost>(p => p.GetRequiredService<ScriptHost>());
                services.AddSingleton<IJobHost>(p => p.GetRequiredService<ScriptHost>());
                services.AddSingleton<IFunctionProvider, ProxyFunctionProvider>();
                services.AddSingleton<IHostedService, WorkerConcurrencyManager>();

                services.AddSingleton<ITypeLocator, ScriptTypeLocator>();
                services.AddSingleton<ScriptSettingsManager>();
                services.AddTransient<IExtensionsManager, ExtensionsManager>();
                services.TryAddSingleton<IHttpRoutesManager, DefaultHttpRouteManager>();
                services.TryAddSingleton<IMetricsLogger, MetricsLogger>();
                services.AddTransient<IExtensionBundleContentProvider, ExtensionBundleContentProvider>();

                // Script binding providers
                services.TryAddEnumerable(ServiceDescriptor.Singleton<IScriptBindingProvider, WebJobsCoreScriptBindingProvider>());
                services.TryAddEnumerable(ServiceDescriptor.Singleton<IScriptBindingProvider, CoreExtensionsScriptBindingProvider>());
                services.TryAddEnumerable(ServiceDescriptor.Singleton<IScriptBindingProvider, GeneralScriptBindingProvider>());

                // Configuration
                services.AddSingleton<IOptions<ScriptApplicationHostOptions>>(new OptionsWrapper<ScriptApplicationHostOptions>(applicationHostOptions));
                services.AddSingleton<IOptionsMonitor<ScriptApplicationHostOptions>>(new ScriptApplicationHostOptionsMonitor(applicationHostOptions));

                services.ConfigureOptions<ScriptJobHostOptionsSetup>();
                services.ConfigureOptions<JobHostFunctionTimeoutOptionsSetup>();
                services.AddOptions<WorkerConcurrencyOptions>();
                services.ConfigureOptions<HttpWorkerOptionsSetup>();
                services.ConfigureOptions<ManagedDependencyOptionsSetup>();
                services.AddOptions<FunctionResultAggregatorOptions>()
                    .Configure<IConfiguration>((o, c) =>
                    {
                        c.GetSection(ConfigurationSectionNames.JobHost)
                         .GetSection(ConfigurationSectionNames.Aggregator)
                         .Bind(o);
                    });
                services.ConfigureOptions<ScaleOptionsSetup>();

                services.AddSingleton<IFileLoggingStatusManager, FileLoggingStatusManager>();

                if (applicationHostOptions.HasParentScope)
                {
                    // Forward the host LanguageWorkerOptions to the Job Host.
                    var languageWorkerOptions = applicationHostOptions.RootServiceProvider.GetService<IOptionsMonitor<LanguageWorkerOptions>>();
                    services.AddSingleton(languageWorkerOptions);
                    services.AddSingleton<IOptions<LanguageWorkerOptions>>(s => new OptionsWrapper<LanguageWorkerOptions>(languageWorkerOptions.CurrentValue));
                    services.ConfigureOptions<JobHostLanguageWorkerOptionsSetup>();
                }
                else
                {
                    services.ConfigureOptions<LanguageWorkerOptionsSetup>();
                    AddCommonServices(services);
                }

                if (SystemEnvironment.Instance.IsKubernetesManagedHosting())
                {
                    services.AddSingleton<IDistributedLockManager, KubernetesDistributedLockManager>();
                }

                services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService, FunctionInvocationDispatcherShutdownManager>());

                services.AddSingleton<IHostOptionsProvider, HostOptionsProvider>();
                services.AddSingleton<IInstanceServicesProviderFactory, ScriptInstanceServicesProviderFactory>();
            });

            RegisterFileProvisioningService(builder);
            return builder;
        }