/// <inheritdoc/> public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder) { var configBuilder = builder.ConfigurationBuilder; var configFolder = Directory.GetParent(Assembly.GetExecutingAssembly().Location).Parent?.FullName; _ = configBuilder.SetBasePath(configFolder); _ = configBuilder.AddJsonFile("functionSettings.json"); _ = configBuilder.AddEnvironmentVariables(); var configuration = configBuilder.Build(); AzureKeyVaultConfigurationOptions azureKeyVaultConfigurationOptions = new AzureKeyVaultConfigurationOptions(configuration[ConfigConstants.KeyVaultUrlConfigKey]) { ReloadInterval = TimeSpan.FromSeconds(double.Parse(configuration[Constants.KeyVaultConfigRefreshDurationSeconds])), }; _ = configBuilder.AddAzureKeyVault(azureKeyVaultConfigurationOptions); configuration = configBuilder.Build(); IConfigurationRefresher configurationRefresher = null; _ = configBuilder.AddAzureAppConfiguration((options) => { _ = options.Connect(configuration[ConfigConstants.AzureAppConfigConnectionstringConfigKey]); _ = options.ConfigureRefresh(refreshOptions => { _ = refreshOptions.Register(ConfigConstants.ForceRefreshConfigKey, "Common", refreshAll: true); }) .Select(KeyFilter.Any, "Common").Select(KeyFilter.Any, "QueueProcessor"); configurationRefresher = options.GetRefresher(); }); }
public void RefreshTests_RefreshIsSkippedIfKvNotInSelectAndCacheIsNotExpired() { IConfigurationRefresher refresher = null; var mockClient = GetMockConfigurationClientSelectKeyLabel(); var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Client = mockClient.Object; options.Select("TestKey2", "label"); options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1", "label") .SetCacheExpiration(TimeSpan.FromSeconds(10)); }); refresher = options.GetRefresher(); }) .Build(); Assert.Equal("TestValue1", config["TestKey1"]); FirstKeyValue.Value = "newValue1"; refresher.RefreshAsync().Wait(); Assert.Equal("TestValue1", config["TestKey1"]); }
static async Task Main(string[] args) { IConfigurationRefresher refresher = null; IConfiguration configuration = null; var builder = new ConfigurationBuilder(); builder.AddAzureAppConfiguration(options => { options .ConnectWithManagedIdentity("https://abc1234configstore.azconfig.io") .ConfigureRefresh(refresh => { refresh .Register("test", refreshAll: true) .SetCacheExpiration(TimeSpan.FromSeconds(1)); }); refresher = options.GetRefresher(); }); configuration = builder.Build(); PrintConfig(configuration); await refresher.Refresh(); PrintConfig(configuration); }
public override void Configure(IFunctionsHostBuilder builder) { // using configuration builder to load the json settings to get the App Config endpoint var tempConfig = new ConfigurationBuilder() .SetBasePath(Environment.CurrentDirectory) .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true) .Build(); IConfigurationRefresher configurationRefresher = null; var configurationRoot = new ConfigurationBuilder() .SetBasePath(Environment.CurrentDirectory) .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .AddAzureAppConfiguration(options => { options .ConnectWithManagedIdentity(tempConfig["AppConfigurationEndpoint"]) .ConfigureRefresh(refresh => { refresh .Register("MyApp1:Sentinel", true) .SetCacheExpiration(TimeSpan.FromSeconds(1)); }); configurationRefresher = options.GetRefresher(); }) .Build(); builder.Services.AddSingleton(configurationRefresher); builder.Services.AddSingleton <IConfiguration>(configurationRoot); }
static void Main(string[] args) { IConfiguration configuration = null; IConfigurationRefresher refresher = null; AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient( new KeyVaultClient .AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); var builder = new ConfigurationBuilder(); builder.AddAzureAppConfiguration(options => { options .ConnectWithManagedIdentity("https://abc1234configstore.azconfig.io") .Use("MyApp1:*") .ConfigureRefresh(refresh => { refresh .Register("MyApp1:Sentinel", refreshAll: true) .SetCacheExpiration(TimeSpan.FromSeconds(1)); }).UseAzureKeyVault(keyVaultClient); refresher = options.GetRefresher(); }); configuration = builder.Build(); PrintConfig(configuration); refresher.Refresh().Wait(); PrintConfig(configuration); }
public TestFunction( IOptionsSnapshot <Test> config, IConfigurationRefresher refresher) { _refresher = refresher; _config = config.Value; }
public override void Configure(IFunctionsHostBuilder builder) { IConfigurationRefresher configurationRefresher = null; // Load configuration from Azure App Configuration ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); configurationBuilder.AddAzureAppConfiguration(options => { options.Connect(Environment.GetEnvironmentVariable("ConnectionString")) // Load all keys that start with `TestApp:` .Select("TestApp:*") // Configure to reload configuration if the registered 'Sentinel' key is modified .ConfigureRefresh(refreshOptions => refreshOptions.Register("TestApp:Settings:Sentinel", refreshAll: true) ) // Indicate to load feature flags .UseFeatureFlags(); configurationRefresher = options.GetRefresher(); }); IConfiguration configuration = configurationBuilder.Build(); // Make settings, feature manager and configuration refresher available through DI builder.Services.Configure <Settings>(configuration.GetSection("TestApp:Settings")); builder.Services.AddFeatureManagement(configuration); builder.Services.AddSingleton <IConfigurationRefresher>(configurationRefresher); }
public void RefreshTests_RefreshIsSkippedIfCacheIsNotExpired() { IConfigurationRefresher refresher = null; var mockClient = GetMockConfigurationClient(); var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Client = mockClient.Object; options.Select("TestKey*"); options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1") .SetCacheExpiration(TimeSpan.FromSeconds(10)); }); refresher = options.GetRefresher(); }) .Build(); Assert.Equal("TestValue1", config["TestKey1"]); FirstKeyValue.Value = "newValue1"; // Wait for some time but not enough to let the cache expire Thread.Sleep(5000); refresher.RefreshAsync().Wait(); Assert.Equal("TestValue1", config["TestKey1"]); }
public TestAppConfig(IConfiguration configuration, IConfigurationRefresherProvider refresherProvider, IFeatureManagerSnapshot featureManagerSnapshot) { isLocal = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID")); _configuration = configuration; _featureManagerSnapshot = featureManagerSnapshot; _configurationRefresher = refresherProvider.Refreshers.First(); }
public CheckFeatures( IConfigurationRefresher configurationRefresher, IFeatureManager featureManager) { _configurationRefresher = configurationRefresher; _featureManager = featureManager; }
public void RefreshTests_SetDirtyForcesNextRefresh() { IConfigurationRefresher refresher = null; var mockClient = GetMockConfigurationClient(); var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Client = mockClient.Object; options.Select("TestKey*"); options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1", "label") .SetCacheExpiration(TimeSpan.FromDays(1)); }); refresher = options.GetRefresher(); }) .Build(); Assert.Equal("TestValue1", config["TestKey1"]); FirstKeyValue.Value = "newValue"; refresher.RefreshAsync().Wait(); Assert.Equal("TestValue1", config["TestKey1"]); refresher.SetDirty(TimeSpan.FromSeconds(1)); // Wait for the cache to expire based on the randomized delay in SetDirty() Thread.Sleep(1200); refresher.RefreshAsync().Wait(); Assert.Equal("newValue", config["TestKey1"]); }
public void SyncTokenUpdatesCorrectNumberOfTimes() { // Arrange var mockResponse = new Mock <Response>(); var mockClient = GetMockConfigurationClient(); IConfigurationRefresher refresher = null; var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Client = mockClient.Object; options.Select("*"); options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1", "label") .SetCacheExpiration(TimeSpan.FromDays(30)); }); refresher = options.GetRefresher(); }) .Build(); foreach (PushNotification pushNotification in _pushNotificationList) { refresher.ProcessPushNotification(pushNotification, TimeSpan.FromSeconds(0)); refresher.RefreshAsync().Wait(); } mockClient.Verify(c => c.GetConfigurationSettingAsync(It.IsAny <ConfigurationSetting>(), It.IsAny <bool>(), It.IsAny <CancellationToken>()), Times.Exactly(_pushNotificationList.Count)); mockClient.Verify(c => c.UpdateSyncToken(It.IsAny <string>()), Times.Exactly(_pushNotificationList.Count)); }
public void RefreshAsyncUpdatesConfig() { // Arrange var mockResponse = new Mock <Response>(); var mockClient = GetMockConfigurationClient(); IConfigurationRefresher refresher = null; var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Client = mockClient.Object; options.Select("*"); options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1", "label") .SetCacheExpiration(TimeSpan.FromDays(30)); }); refresher = options.GetRefresher(); }) .Build(); Assert.Equal("TestValue1", config["TestKey1"]); FirstKeyValue.Value = "newValue1"; refresher.ProcessPushNotification(_pushNotificationList.First(), TimeSpan.FromSeconds(0)); refresher.RefreshAsync().Wait(); Assert.Equal("newValue1", config["TestKey1"]); }
public Function1( IConfiguration configuration, IConfigurationRefresher configurationRefresher) { _configuration = configuration; _configurationRefresher = configurationRefresher; }
public void ProcessPushNotificationThrowsArgumentExceptions() { var mockResponse = new Mock <Response>(); var mockClient = GetMockConfigurationClient(); IConfigurationRefresher refresher = null; var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Client = mockClient.Object; options.Select("*"); options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1", "label") .SetCacheExpiration(TimeSpan.FromDays(30)); }); refresher = options.GetRefresher(); }) .Build(); foreach (PushNotification invalidPushNotification in _invalidPushNotificationList) { Action action = () => refresher.ProcessPushNotification(invalidPushNotification); Assert.Throws <ArgumentException>(action); } PushNotification nullPushNotification = null; Action nullAction = () => refresher.ProcessPushNotification(nullPushNotification); Assert.Throws <ArgumentNullException>(nullAction); }
public void RefreshTests_TryRefreshAsyncReturnsFalseOnRequestFailedException() { IConfigurationRefresher refresher = null; var mockClient = GetMockConfigurationClient(); var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Client = mockClient.Object; options.Select("TestKey*"); options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1") .SetCacheExpiration(TimeSpan.FromSeconds(1)); }); refresher = options.GetRefresher(); }) .Build(); Assert.Equal("TestValue1", config["TestKey1"]); FirstKeyValue.Value = "newValue"; mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Throws(new RequestFailedException("Request failed.")); // Wait for the cache to expire Thread.Sleep(1500); bool result = refresher.TryRefreshAsync().Result; Assert.False(result); Assert.NotEqual("newValue", config["TestKey1"]); }
public void RefreshTests_TryRefreshAsyncUpdatesConfigurationAndReturnsTrueOnSuccess() { IConfigurationRefresher refresher = null; var mockClient = GetMockConfigurationClient(); var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Client = mockClient.Object; options.Select("TestKey*"); options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1") .SetCacheExpiration(TimeSpan.FromSeconds(1)); }); refresher = options.GetRefresher(); }) .Build(); Assert.Equal("TestValue1", config["TestKey1"]); FirstKeyValue.Value = "newValue"; // Wait for the cache to expire Thread.Sleep(1500); bool result = refresher.TryRefreshAsync().Result; Assert.True(result); Assert.Equal("newValue", config["TestKey1"]); }
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { var settings = config.Build(); config.AddAzureAppConfiguration(options => { options.Connect(settings["Connection:AzConnectionString"]) .ConfigureRefresh(refresh => { refresh.Register("Settings:ArchivePath", "Home") .Register("Settings:Enabled", "Home") .Register("Settings:FlipHorizontal", "Home") .Register("Settings:FlipVertical", "Home") .Register("Settings:Frequency", "Home") .Register("Settings:RawPath", "Home") .Register("Settings:ReadyToUploadPath", "Home") .SetCacheExpiration(TimeSpan.FromSeconds(120)); }); _refresher = options.GetRefresher(); _timer = new Timer(async(o) => { await Program._refresher.RefreshAsync(); }, null, TimeSpan.FromSeconds(10), TimeSpan.FromMinutes(2)); }); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup <Startup>(); webBuilder.UseUrls("http://*:786"); });
public LoaderIO( IConfigurationRoot configuration, IConfigurationRefresher configurationRefresher) { _configuration = configuration; _configurationRefresher = configurationRefresher; }
static BlobTriggerCSharp() { var builder = new ConfigurationBuilder(); isLocal = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID")); if (isLocal) { var appConfLocal = Environment.GetEnvironmentVariable("KeyConnectionString"); builder.AddAzureAppConfiguration(appConfLocal); } else { builder.AddAzureAppConfiguration(options => { options.Connect(new Uri(Environment.GetEnvironmentVariable("EndpointURL")), new ManagedIdentityCredential()) .ConfigureKeyVault(kv => { kv.SetCredential(new DefaultAzureCredential()); }); ConfigurationRefresher = options.GetRefresher(); }); } Configuration = builder.Build(); }
public LeeBus(IConfiguration configuration, IConfigurationRefresherProvider refresherProvider, IFeatureManagerSnapshot featureManagerSnapshot) { isLocal = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID")); _configuration = configuration; _featureManagerSnapshot = featureManagerSnapshot; _configurationRefresher = refresherProvider.Refreshers.First(); connString = Environment.GetEnvironmentVariable("SqlServerConnection"); }
public async Task RefreshTests_UpdatesAllSettingsIfInitialLoadFails() { var mockResponse = new Mock <Response>(); var mockClient = new Mock <ConfigurationClient>(MockBehavior.Strict, TestHelpers.CreateMockEndpointString()); mockClient.SetupSequence(c => c.GetConfigurationSettingsAsync(It.IsAny <SettingSelector>(), It.IsAny <CancellationToken>())) .Throws(new RequestFailedException("Request failed")) .Throws(new RequestFailedException("Request failed")) .Returns(new MockAsyncPageable(_kvCollection)); mockClient.SetupSequence(c => c.GetConfigurationSettingAsync("TestKey1", It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(Response.FromValue(_kvCollection.FirstOrDefault(s => s.Key == "TestKey1" && s.Label == "label"), mockResponse.Object))); IConfigurationRefresher refresher = null; IConfiguration configuration = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Select("TestKey*"); options.Client = mockClient.Object; options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1", "label") .SetCacheExpiration(TimeSpan.FromSeconds(1)); }); refresher = options.GetRefresher(); }, optional: true) .Build(); // Validate initial load failed to retrieve any setting Assert.Null(configuration["TestKey1"]); Assert.Null(configuration["TestKey2"]); Assert.Null(configuration["TestKey3"]); // Act await Assert.ThrowsAsync <RequestFailedException>(async() => { await refresher.RefreshAsync(); }); await refresher.RefreshAsync(); Assert.Null(configuration["TestKey1"]); Assert.Null(configuration["TestKey2"]); Assert.Null(configuration["TestKey3"]); // Wait for the cache to expire Thread.Sleep(1500); await refresher.RefreshAsync(); // Validate all settings were loaded, including the ones not registered for refresh Assert.Equal("TestValue1", configuration["TestKey1"]); Assert.Equal("TestValue2", configuration["TestKey2"]); Assert.Equal("TestValue3", configuration["TestKey3"]); }
public static IHostBuilder CreateHostBuilder(string[] args) { return(Host.CreateDefaultBuilder(args) // Configures app as Windows Service .UseWindowsService() // Configures other services, Options objects .ConfigureServices((hostContext, services) => { var storageSettings = hostContext.Configuration.GetSection("Storage"); services.Configure <StorageSettings>(storageSettings); services.AddHostedService <Worker>(); services.AddApplicationInsightsTelemetryWorkerService(); }) // Sets up Azure App Config .ConfigureAppConfiguration((hostContext, config) => { var settings = config.Build(); var applicationConfigurationEndpoint = hostContext.HostingEnvironment.IsDevelopment() // Gets Azure App Config details from KeyVault ? KeyVaultClient .GetSecretAsync(settings["KeyVault"], "ApplicationConfiguration-ConnectionString") .Result.Value // Falls back to app.settings.json : settings["AppConfiguration:ConnectionString"]; config.AddAzureAppConfiguration(options => { var appConfigurationOptions = hostContext.HostingEnvironment.IsDevelopment() // Uses connections string ? options.Connect(applicationConfigurationEndpoint) // Uses Azure Managed Identity : options.Connect(new Uri(applicationConfigurationEndpoint), new ManagedIdentityCredential()); appConfigurationOptions .ConfigureRefresh(refresh => { refresh.Register("Storage:ConnectionString", "Label1") .Register("ApplicationInsights:InstrumentationKey", "Label1") .SetCacheExpiration(TimeSpan.FromSeconds(1)); }) .UseAzureKeyVault(KeyVaultClient); // Settings Auto-Refresh _refresher = options.GetRefresher(); _timer = new Timer(async _ => await _refresher.Refresh().ConfigureAwait(false), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); }); })); }
public MyAppConfigurationRefreshMiddleware(RequestDelegate next, IConfiguration configuration) { _next = next ?? throw new ArgumentNullException(nameof(next)); if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } _refresher = ((IConfigurationRoot)configuration).Providers.FirstOrDefault(p => p is IConfigurationRefresher) as IConfigurationRefresher; }
public ConfigurationSaver(IOptionsSnapshot <Options.AzureAppConfigurationOptions> optionsAccessor, ITypedConfiguration <TOptions> typedConfiguration, IConfigurationRefresher configurationRefresher) { #region null checks if (optionsAccessor is null) { throw new ArgumentNullException(nameof(optionsAccessor)); } #endregion configurationClient = new ConfigurationClient(optionsAccessor.Value.ConnectionString); this.typedConfiguration = typedConfiguration ?? throw new ArgumentNullException(nameof(typedConfiguration)); this.configurationRefresher = configurationRefresher ?? throw new ArgumentNullException(nameof(configurationRefresher)); }
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder) { string appConfigUri = Environment.GetEnvironmentVariable("AppConfigEndpoint"); builder.ConfigurationBuilder.AddAzureAppConfiguration(options => { options.Connect(new Uri(appConfigUri), new ManagedIdentityCredential()) .ConfigureRefresh(ro => ro.Register("debugMode", LabelFilter.Null, refreshAll: true) .SetCacheExpiration(TimeSpan.FromSeconds(60))); ConfigurationRefresher = options.GetRefresher(); }); }
public void RefreshTests_TryRefreshAsyncReturnsFalseForAuthenticationFailedException() { IConfigurationRefresher refresher = null; var mockResponse = new Mock <Response>(); var mockClient = new Mock <ConfigurationClient>(MockBehavior.Strict, TestHelpers.CreateMockEndpointString()); mockClient.SetupSequence(c => c.GetConfigurationSettingsAsync(It.IsAny <SettingSelector>(), It.IsAny <CancellationToken>())) .Returns(new MockAsyncPageable(_kvCollection)); var innerException = new AuthenticationFailedException("Authentication failed.") { Source = "Azure.Identity" }; mockClient.SetupSequence(c => c.GetConfigurationSettingAsync("TestKey1", It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(Response.FromValue(_kvCollection.FirstOrDefault(s => s.Key == "TestKey1"), mockResponse.Object))) .Returns(Task.FromResult(Response.FromValue(_kvCollection.FirstOrDefault(s => s.Key == "TestKey1"), mockResponse.Object))) .Throws(new KeyVaultReferenceException(innerException.Message, innerException)); var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Client = mockClient.Object; options.Select("TestKey*"); options.ConfigureRefresh(refreshOptions => { refreshOptions.Register("TestKey1") .SetCacheExpiration(TimeSpan.FromSeconds(1)); }); refresher = options.GetRefresher(); }) .Build(); Assert.Equal("TestValue1", config["TestKey1"]); FirstKeyValue.Value = "newValue"; // Wait for the cache to expire Thread.Sleep(1500); // Second call to GetConfigurationSettingAsync does not throw Assert.True(refresher.TryRefreshAsync().Result); // Wait for the cache to expire Thread.Sleep(1500); // Third call to GetConfigurationSettingAsync throws KeyVaultReferenceException Assert.False(refresher.TryRefreshAsync().Result); }
static HttpTriggeredFunc() { var builder = new ConfigurationBuilder(); builder.AddAzureAppConfiguration(options => { options.Connect(Environment.GetEnvironmentVariable("ConnectionString")) .ConfigureRefresh(refreshOptions => refreshOptions.Register("TestApp:Settings:Message") .SetCacheExpiration(TimeSpan.FromSeconds(60)) ); ConfigurationRefresher = options.GetRefresher(); }); Configuration = builder.Build(); }
static SalesProc() { var builder = new ConfigurationBuilder(); builder.AddAzureAppConfiguration(options => { options.Connect(Environment.GetEnvironmentVariable("ConnectionString")) .ConfigureRefresh(refreshOptions => refreshOptions.Register("SalesProc:Transform:CSV") .SetCacheExpiration(TimeSpan.FromSeconds(60)) ); ConfigurationRefresher = options.GetRefresher(); }); Configuration = builder.Build(); }
public override void Configure(IFunctionsHostBuilder builder) { var regionName = Environment.GetEnvironmentVariable(Constants.EnvironmentVariables.RegionName); if (string.IsNullOrWhiteSpace(regionName)) { // Default to EastUS2 if the environment variable is missing/empty. regionName = Regions.EastUS2; } // Register the CosmosClient as a Singleton // Optimize for preferred geo-region builder.Services.AddSingleton((s) => { CosmosClientBuilder configurationBuilder = new CosmosClientBuilder(Configuration[Constants.CosmosDb.Connection]) .WithApplicationRegion(regionName); return(configurationBuilder.Build()); }); // Load configuration from Azure App Configuration ConfigurationBuilder.AddAzureAppConfiguration(options => { // Use ".Connect(...)" for connection string, or use ".ConnectWithManagedIdentity(...) for managed identity" options.Connect(Environment.GetEnvironmentVariable("AzureAppConfigConnectionString")) // Load all keys that start with `EnterpriseServerless:` .Select("EnterpriseServerless:*") // Configure to reload configuration if the registered 'Sentinel' key is modified .ConfigureRefresh(refreshOptions => refreshOptions.Register(key: "EnterpriseServerless:Sentinel", label: LabelFilter.Null, refreshAll: true) .SetCacheExpiration(TimeSpan.FromSeconds(30)) ) // Indicate to load feature flags .UseFeatureFlags(); ConfigurationRefresher = options.GetRefresher(); }); Configuration = ConfigurationBuilder.Build(); builder.Services.AddLogging(); builder.Services.AddSingleton(Configuration); builder.Services.AddSingleton(ConfigurationRefresher); builder.Services.AddFeatureManagement(Configuration); builder.Services.AddSingleton <IStartCallService, StartCallService>(); builder.Services.AddSingleton <ICallLoggingService, CallLoggingService>(); builder.Services.AddSingleton <IMediaFileService, MediaFileService>(); builder.Services.AddSingleton <IPostCallService, PostCallService>(); }