public void ConfigureServices()

in src/Service/Startup.cs [89:321]


        public void ConfigureServices(IServiceCollection services)
        {
            Startup.AddValidFilters();
            services.AddSingleton(_hotReloadEventHandler);
            string configFileName = Configuration.GetValue<string>("ConfigFileName") ?? FileSystemRuntimeConfigLoader.DEFAULT_CONFIG_FILE_NAME;
            string? connectionString = Configuration.GetValue<string?>(
                FileSystemRuntimeConfigLoader.RUNTIME_ENV_CONNECTION_STRING.Replace(FileSystemRuntimeConfigLoader.ENVIRONMENT_PREFIX, ""),
                null);
            IFileSystem fileSystem = new FileSystem();
            FileSystemRuntimeConfigLoader configLoader = new(fileSystem, _hotReloadEventHandler, configFileName, connectionString);
            RuntimeConfigProvider configProvider = new(configLoader);
            _configProvider = configProvider;

            services.AddSingleton(fileSystem);
            services.AddSingleton(configLoader);
            services.AddSingleton(configProvider);

            bool runtimeConfigAvailable = configProvider.TryGetConfig(out RuntimeConfig? runtimeConfig);

            if (runtimeConfigAvailable
                && runtimeConfig?.Runtime?.Telemetry?.ApplicationInsights is not null
                && runtimeConfig.Runtime.Telemetry.ApplicationInsights.Enabled)
            {
                // Add ApplicationTelemetry service and register
                // custom ITelemetryInitializer implementation with the dependency injection
                services.AddApplicationInsightsTelemetry();
                services.AddSingleton<ITelemetryInitializer, AppInsightsTelemetryInitializer>();
            }

            if (runtimeConfigAvailable
                && runtimeConfig?.Runtime?.Telemetry?.OpenTelemetry is not null
                && runtimeConfig.Runtime.Telemetry.OpenTelemetry.Enabled)
            {
                services.Configure<OpenTelemetryLoggerOptions>(options =>
                {
                    options.IncludeScopes = true;
                    options.ParseStateValues = true;
                    options.IncludeFormattedMessage = true;
                });
                services.AddOpenTelemetry()
                .WithLogging(logging =>
                {
                    logging.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(runtimeConfig.Runtime.Telemetry.OpenTelemetry.ServiceName!))
                    .AddOtlpExporter(configure =>
                    {
                        configure.Endpoint = new Uri(runtimeConfig.Runtime.Telemetry.OpenTelemetry.Endpoint!);
                        configure.Headers = runtimeConfig.Runtime.Telemetry.OpenTelemetry.Headers;
                        configure.Protocol = OtlpExportProtocol.Grpc;
                    });

                })
                .WithMetrics(metrics =>
                {
                    metrics.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(runtimeConfig.Runtime.Telemetry.OpenTelemetry.ServiceName!))
                        .AddOtlpExporter(configure =>
                        {
                            configure.Endpoint = new Uri(runtimeConfig.Runtime.Telemetry.OpenTelemetry.Endpoint!);
                            configure.Headers = runtimeConfig.Runtime.Telemetry.OpenTelemetry.Headers;
                            configure.Protocol = OtlpExportProtocol.Grpc;
                        })
                        .AddMeter(TelemetryMetricsHelper.MeterName);
                })
                .WithTracing(tracing =>
                {
                    tracing.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(runtimeConfig.Runtime.Telemetry.OpenTelemetry.ServiceName!))
                        .AddHttpClientInstrumentation()
                        .AddOtlpExporter(configure =>
                        {
                            configure.Endpoint = new Uri(runtimeConfig.Runtime.Telemetry.OpenTelemetry.Endpoint!);
                            configure.Headers = runtimeConfig.Runtime.Telemetry.OpenTelemetry.Headers;
                            configure.Protocol = OtlpExportProtocol.Grpc;
                        })
                        .AddSource(TelemetryTracesHelper.DABActivitySource.Name);
                });
            }

            services.AddSingleton(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(RuntimeConfigValidator).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<RuntimeConfigValidator>();
            });
            services.AddSingleton<RuntimeConfigValidator>();

            services.AddSingleton<CosmosClientProvider>();
            services.AddHealthChecks()
                .AddCheck<BasicHealthCheck>(nameof(BasicHealthCheck));

            services.AddSingleton<ILogger<SqlQueryEngine>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(SqlQueryEngine).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<SqlQueryEngine>();
            });

            services.AddSingleton<ILogger<IQueryExecutor>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(IQueryExecutor).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<IQueryExecutor>();
            });

            services.AddSingleton<ILogger<ISqlMetadataProvider>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(ISqlMetadataProvider).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<ISqlMetadataProvider>();
            });

            // Below are the factory registrations that will enable multiple databases scenario.
            // within these factories the various instances will be created based on the database type and datasourceName.
            services.AddSingleton<IAbstractQueryManagerFactory, QueryManagerFactory>();

            services.AddSingleton<IQueryEngineFactory, QueryEngineFactory>();

            services.AddSingleton<IMutationEngineFactory, MutationEngineFactory>();

            services.AddSingleton<IMetadataProviderFactory, MetadataProviderFactory>();

            services.AddSingleton<GraphQLSchemaCreator>();
            services.AddSingleton<GQLFilterParser>();
            services.AddSingleton<RequestValidator>();
            services.AddSingleton<RestService>();
            services.AddSingleton<HealthCheckHelper>();
            services.AddSingleton<HttpUtilities>();
            services.AddSingleton<BasicHealthReportResponseWriter>();
            services.AddSingleton<ComprehensiveHealthReportResponseWriter>();

            // ILogger explicit creation required for logger to use --LogLevel startup argument specified.
            services.AddSingleton<ILogger<BasicHealthReportResponseWriter>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(BasicHealthReportResponseWriter).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<BasicHealthReportResponseWriter>();
            });

            // ILogger explicit creation required for logger to use --LogLevel startup argument specified.
            services.AddSingleton<ILogger<ComprehensiveHealthReportResponseWriter>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(ComprehensiveHealthReportResponseWriter).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<ComprehensiveHealthReportResponseWriter>();
            });

            // ILogger explicit creation required for logger to use --LogLevel startup argument specified.
            services.AddSingleton<ILogger<HealthCheckHelper>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(HealthCheckHelper).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<HealthCheckHelper>();
            });

            // ILogger explicit creation required for logger to use --LogLevel startup argument specified.
            services.AddSingleton<ILogger<HttpUtilities>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(HttpUtilities).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<HttpUtilities>();
            });

            services.AddSingleton<ILogger<RestController>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(RestController).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<RestController>();
            });

            services.AddSingleton<ILogger<ClientRoleHeaderAuthenticationMiddleware>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelRuntime = new(MinimumLogLevel, typeof(ClientRoleHeaderAuthenticationMiddleware).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelRuntime);
                return loggerFactory.CreateLogger<ClientRoleHeaderAuthenticationMiddleware>();
            });

            services.AddSingleton<ILogger<ConfigurationController>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(ConfigurationController).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<ConfigurationController>();
            });

            //Enable accessing HttpContext in RestService to get ClaimsPrincipal.
            services.AddHttpContextAccessor();

            if (runtimeConfig is not null && runtimeConfig.Runtime?.Host?.Mode is HostMode.Development)
            {
                // Development mode implies support for "Hot Reload". The V2 authentication function
                // wires up all DAB supported authentication providers (schemes) so that at request time,
                // the runtime config defined authentication provider is used to authenticate requests.
                ConfigureAuthenticationV2(services, configProvider);
            }
            else
            {
                ConfigureAuthentication(services, configProvider);
            }

            services.AddAuthorization();
            services.AddSingleton<ILogger<IAuthorizationHandler>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(IAuthorizationHandler).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<IAuthorizationHandler>();
            });
            services.AddSingleton<ILogger<IAuthorizationResolver>>(implementationFactory: (serviceProvider) =>
            {
                LogLevelInitializer logLevelInit = new(MinimumLogLevel, typeof(IAuthorizationResolver).FullName, _configProvider, _hotReloadEventHandler);
                ILoggerFactory? loggerFactory = CreateLoggerFactoryForHostedAndNonHostedScenario(serviceProvider, logLevelInit);
                return loggerFactory.CreateLogger<IAuthorizationResolver>();
            });

            services.AddSingleton<IAuthorizationHandler, RestAuthorizationHandler>();
            services.AddSingleton<IAuthorizationResolver, AuthorizationResolver>();
            services.AddSingleton<IOpenApiDocumentor, OpenApiDocumentor>();

            AddGraphQLService(services, runtimeConfig?.Runtime?.GraphQL);

            // Subscribe the GraphQL schema refresh method to the specific hot-reload event
            _hotReloadEventHandler.Subscribe(DabConfigEvents.GRAPHQL_SCHEMA_REFRESH_ON_CONFIG_CHANGED, (sender, args) => RefreshGraphQLSchema(services));

            services.AddFusionCache()
                .WithOptions(options =>
                {
                    options.FactoryErrorsLogLevel = LogLevel.Debug;
                    options.EventHandlingErrorsLogLevel = LogLevel.Debug;
                })
                .WithDefaultEntryOptions(new FusionCacheEntryOptions
                {
                    Duration = TimeSpan.FromSeconds(5)
                });

            services.AddSingleton<DabCacheService>();
            services.AddControllers();
        }