public void ConfigureServices()

in DeviceBridge/Startup.cs [45:114]


        public void ConfigureServices(IServiceCollection services)
        {
            _logger.Info("Configuring services");

            string kvUrl = Environment.GetEnvironmentVariable("KV_URL");

            // Build cache from Key Vault
            var secretsService = new SecretsProvider(kvUrl);
            var idScope = secretsService.GetIdScopeAsync(_logger).Result;
            var sasKey = secretsService.GetIotcSasKeyAsync(_logger).Result;
            var sqlConnectionString = Utils.GetSqlConnectionString(_logger, secretsService);

            // Override defaults
            var customMaxPoolSize = Environment.GetEnvironmentVariable("MAX_POOL_SIZE");
            var customConnectionBatchSize = Environment.GetEnvironmentVariable("DEVICE_CONNECTION_BATCH_SIZE");
            var customConnectionBatchIntervalMs = Environment.GetEnvironmentVariable("DEVICE_CONNECTION_BATCH_INTERVAL_MS");
            uint maxPoolSize = (customMaxPoolSize != null && customMaxPoolSize != string.Empty) ? Convert.ToUInt32(customMaxPoolSize, 10) : ConnectionManager.DeafultMaxPoolSize;
            uint rampupBatchSize = (customConnectionBatchSize != null && customConnectionBatchSize != string.Empty) ? Convert.ToUInt32(customConnectionBatchSize, 10) : SubscriptionScheduler.DefaultConnectionBatchSize;
            uint rampupBatchIntervalMs = (customConnectionBatchIntervalMs != null && customConnectionBatchIntervalMs != string.Empty) ? Convert.ToUInt32(customConnectionBatchIntervalMs, 10) : SubscriptionScheduler.DefaultConnectionBatchIntervalMs;

            _logger.SetProperty("idScope", idScope);
            _logger.SetProperty("cv", Guid.NewGuid()); // CV for all background operations

            services.AddHttpContextAccessor();

            // Start services
            services.AddSingleton<ISecretsProvider>(secretsService);
            services.AddSingleton(_logger);
            services.AddSingleton<IEncryptionService, EncryptionService>();
            services.AddSingleton<IStorageProvider>(provider => new StorageProvider(sqlConnectionString, provider.GetRequiredService<IEncryptionService>()));
            services.AddSingleton<IConnectionManager>(provider => new ConnectionManager(provider.GetRequiredService<Logger>(), idScope, sasKey, maxPoolSize, provider.GetRequiredService<IStorageProvider>()));
            services.AddSingleton<ISubscriptionCallbackFactory, SubscriptionCallbackFactory>();
            services.AddSingleton<IConnectionStatusSubscriptionService, ConnectionStatusSubscriptionService>();
            services.AddSingleton<IDataSubscriptionService, DataSubscriptionService>();
            services.AddSingleton<ISubscriptionScheduler>(provider => new SubscriptionScheduler(provider.GetRequiredService<Logger>(), provider.GetRequiredService<IConnectionManager>(), provider.GetRequiredService<IStorageProvider>(), provider.GetRequiredService<ISubscriptionCallbackFactory>(), rampupBatchSize, rampupBatchIntervalMs));
            services.AddSingleton<IBridgeService, BridgeService>();
            services.AddHttpClient("RetryClient").AddPolicyHandler(GetRetryPolicy(_logger));

            services.AddHostedService<ExpiredConnectionCleanupHostedService>();
            services.AddHostedService<SubscriptionStartupHostedService>();
            services.AddHostedService<SubscriptionSchedulerHostedService>();
            services.AddHostedService<HubCacheGcHostedService>();

            services.AddAuthentication(o =>
            {
                o.DefaultScheme = SchemesNamesConst.TokenAuthenticationDefaultScheme;
            })
            .AddScheme<TokenAuthenticationOptions, TokenAuthenticationHandler>(SchemesNamesConst.TokenAuthenticationDefaultScheme, o => { });

            services.AddControllers(options =>
            {
                options.Filters.Add(new AuthorizeFilter());
            });

            services.AddHealthChecks();

            services.AddSwaggerGen(options =>
            {
                // Set XML comments.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                options.IncludeXmlComments(xmlPath);

                options.CustomOperationIds(apiDesc => apiDesc.TryGetMethodInfo(out MethodInfo methodInfo) ? methodInfo.Name : null);

                // Type mappers for custom serialization.
                options.MapType(typeof(DeviceSubscriptionType), () => DeviceSubscriptionType.Schema);
                options.MapType(typeof(DeviceTwin), () => DeviceTwin.Schema);
            });
        }