public static IHostBuilder AddScriptHost(this IHostBuilder builder, ScriptApplicationHostOptions applicationOptions, ILoggerFactory loggerFactory, IMetricsLogger metricsLogger, Action <IWebJobsBuilder> configureWebJobs = null) { loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; builder.SetAzureFunctionsConfigurationRoot(); // Host configuration builder.ConfigureLogging((context, loggingBuilder) => { loggingBuilder.AddDefaultWebJobsFilters(); string loggingPath = ConfigurationPath.Combine(ConfigurationSectionNames.JobHost, "Logging"); loggingBuilder.AddConfiguration(context.Configuration.GetSection(loggingPath)); loggingBuilder.Services.AddSingleton <IFileWriterFactory, DefaultFileWriterFactory>(); loggingBuilder.Services.AddSingleton <ILoggerProvider, HostFileLoggerProvider>(); loggingBuilder.Services.AddSingleton <ILoggerProvider, FunctionFileLoggerProvider>(); loggingBuilder.AddConsoleIfEnabled(context); ConfigureApplicationInsights(context, loggingBuilder); }) .ConfigureAppConfiguration((context, configBuilder) => { if (!context.Properties.ContainsKey(ScriptConstants.SkipHostJsonConfigurationKey)) { configBuilder.Add(new HostJsonFileConfigurationSource(applicationOptions, SystemEnvironment.Instance, loggerFactory, metricsLogger)); } }); // WebJobs configuration builder.AddScriptHostCore(applicationOptions, configureWebJobs, loggerFactory); // Allow FunctionsStartup to add configuration after all other configuration is registered. builder.ConfigureAppConfiguration((context, configBuilder) => { // Pre-build configuration here to load bundles and to store for later validation. var config = configBuilder.Build(); var extensionBundleOptions = GetExtensionBundleOptions(config); var bundleManager = new ExtensionBundleManager(extensionBundleOptions, SystemEnvironment.Instance, loggerFactory); var metadataServiceManager = applicationOptions.RootServiceProvider.GetService <IFunctionMetadataManager>(); var languageWorkerOptions = applicationOptions.RootServiceProvider.GetService <IOptions <LanguageWorkerOptions> >(); var locator = new ScriptStartupTypeLocator(applicationOptions.ScriptPath, loggerFactory.CreateLogger <ScriptStartupTypeLocator>(), bundleManager, metadataServiceManager, metricsLogger, languageWorkerOptions); // The locator (and thus the bundle manager) need to be created now in order to configure app configuration. // Store them so they do not need to be re-created later when configuring services. context.Properties[BundleManagerKey] = bundleManager; context.Properties[StartupTypeLocatorKey] = locator; // If we're skipping host initialization, this key will not exist and this will also be skipped. if (context.Properties.TryGetValue(DelayedConfigurationActionKey, out object actionObject) && actionObject is Action <IWebJobsStartupTypeLocator> delayedConfigAction) { context.Properties.Remove(DelayedConfigurationActionKey); delayedConfigAction(locator); // store the snapshot for validation later, but only if there // are any registered external configuration startups. if (locator.HasExternalConfigurationStartups()) { context.Properties[ConfigurationSnapshotKey] = config; } } }); return(builder); }
public static IHostBuilder AddScriptHostCore(this IHostBuilder builder, ScriptApplicationHostOptions applicationHostOptions, Action <IWebJobsBuilder> configureWebJobs = null, ILoggerFactory loggerFactory = null) { var skipHostInitialization = builder.Properties.ContainsKey(ScriptConstants.SkipHostInitializationKey); builder.ConfigureWebJobs((context, webJobsBuilder) => { // Built in binding registrations webJobsBuilder.AddExecutionContextBinding(o => { o.AppDirectory = applicationHostOptions.ScriptPath; }) .AddHttp(o => { o.SetResponse = HttpBinding.SetResponse; }) .AddTimers() .AddManualTrigger() .AddWarmup(); var extensionBundleOptions = GetExtensionBundleOptions(context); var bundleManager = new ExtensionBundleManager(extensionBundleOptions, SystemEnvironment.Instance, loggerFactory); webJobsBuilder.Services.AddSingleton <IExtensionBundleManager>(_ => bundleManager); if (!skipHostInitialization) { // Only set our external startup if we're not suppressing host initialization // as we don't want to load user assemblies otherwise. webJobsBuilder.UseScriptExternalStartup(applicationHostOptions, loggerFactory, bundleManager); } configureWebJobs?.Invoke(webJobsBuilder); }, o => o.AllowPartialHostStartup = true); // 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>(); services.AddSingleton <IFunctionDispatcher, RpcFunctionInvocationDispatcher>(); services.AddSingleton <IJobHostLanguageWorkerChannelManager, JobHostLanguageWorkerChannelManager>(); services.AddSingleton <IFunctionDispatcherLoadBalancer, FunctionDispatcherLoadBalancer>(); services.AddSingleton <IScriptJobHost>(p => p.GetRequiredService <ScriptHost>()); services.AddSingleton <IJobHost>(p => p.GetRequiredService <ScriptHost>()); services.AddSingleton <IFunctionMetadataManager, FunctionMetadataManager>(); services.AddSingleton <IProxyMetadataManager, ProxyMetadataManager>(); services.AddSingleton <ITypeLocator, ScriptTypeLocator>(); services.AddSingleton <ScriptSettingsManager>(); services.AddTransient <IExtensionsManager, ExtensionsManager>(); services.TryAddSingleton <IHttpRoutesManager, DefaultHttpRouteManager>(); services.TryAddSingleton <IMetricsLogger, MetricsLogger>(); services.TryAddSingleton <IScriptJobHostEnvironment, ConsoleScriptJobHostEnvironment>(); 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 <ScriptHostOptionsSetup>(); services.ConfigureOptions <JobHostFunctionTimeoutOptionsSetup>(); // TODO: pgopa only add this to WebHostServiceCollection services.ConfigureOptions <LanguageWorkerOptionsSetup>(); services.ConfigureOptions <ManagedDependencyOptionsSetup>(); services.AddOptions <FunctionResultAggregatorOptions>() .Configure <IConfiguration>((o, c) => { c.GetSection(ConfigurationSectionNames.JobHost) .GetSection(ConfigurationSectionNames.Aggregator) .Bind(o); }); services.AddOptions <ScaleOptions>() .Configure <IConfiguration>((o, c) => { c.GetSection(ConfigurationSectionNames.JobHost) .GetSection(ConfigurationSectionNames.Scale) .Bind(o); }); services.AddSingleton <IFileLoggingStatusManager, FileLoggingStatusManager>(); services.AddSingleton <IPrimaryHostStateProvider, PrimaryHostStateProvider>(); if (!applicationHostOptions.HasParentScope) { AddCommonServices(services); } services.AddSingleton <IHostedService, LanguageWorkerConsoleLogService>(); services.TryAddEnumerable(ServiceDescriptor.Singleton <IHostedService, PrimaryHostCoordinator>()); if (SystemEnvironment.Instance.IsRuntimeScaleMonitoringEnabled()) { services.TryAddEnumerable(ServiceDescriptor.Singleton <IHostedService, FunctionsScaleMonitorService>()); } services.TryAddSingleton <FunctionsScaleManager>(); }); RegisterFileProvisioningService(builder); return(builder); }