Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
using Azure.Core;
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
Expand Down Expand Up @@ -63,6 +64,30 @@ public static IConfigurationBuilder AddAzureAppConfiguration(
return configurationBuilder.AddAzureAppConfiguration(options => options.Connect(connectionStrings), optional);
}

/// <summary>
/// Adds key-value data from an Azure App Configuration store to a configuration builder.
/// </summary>
/// <param name="configurationBuilder">The configuration builder to add key-values to.</param>
/// <param name="endpoint">The endpoint used to connect to the configuration store.</param>
/// <param name="credential">The <see cref="TokenCredential"/> used to authenticate requests to the configuration store.</param>
/// <param name="optional">Determines the behavior of the App Configuration provider when an exception occurs while loading data from server. If false, the exception is thrown. If true, the exception is suppressed and no settings are populated from Azure App Configuration.
/// <exception cref="ArgumentException"/> will always be thrown when the caller gives an invalid input configuration (connection strings, endpoints, key/label filters...etc).
/// </param>
/// <returns>The provided configuration builder.</returns>
public static IConfigurationBuilder AddAzureAppConfiguration(
this IConfigurationBuilder configurationBuilder,
Uri endpoint,
TokenCredential credential,
bool optional = false)
{
var source = new AzureAppConfigurationSource((options) =>
{
options.Connect(endpoint, credential);
}, optional);

return configurationBuilder.Add(source);
}

/// <summary>
/// Adds key-value data from an Azure App Configuration store to a configuration builder.
/// </summary>
Expand Down
20 changes: 20 additions & 0 deletions tests/Tests.AzureAppConfiguration/Integration/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ private class TestContext
}

private ConfigurationClient _configClient;
private Uri _configEndpoint;

private SecretClient _secretClient;

Expand Down Expand Up @@ -149,6 +150,8 @@ public async Task InitializeAsync()
throw new InvalidOperationException($"App Configuration store '{AppConfigStoreName}' not found in resource group '{ResourceGroupName}'. Please create it before running tests.", ex);
}

_configEndpoint = new Uri(appConfigStore.Data.Endpoint);

AsyncPageable<AppConfigurationStoreApiKey> accessKeys = appConfigStore.GetKeysAsync();

_connectionString = (await accessKeys.FirstAsync()).ConnectionString;
Expand Down Expand Up @@ -448,6 +451,23 @@ public async Task LoadConfiguration_RetrievesValuesFromAppConfiguration()
Assert.Equal("InitialValue2", config[$"{testContext.KeyPrefix}:Setting2"]);
}

[Fact]
public async Task LoadConfiguration_TokenCredentialHelperOverloadWorks()
{
// Arrange - Setup test-specific keys
TestContext testContext = CreateTestContext("BasicConfig");
await SetupKeyValues(testContext);

// Act
var config = new ConfigurationBuilder()
.AddAzureAppConfiguration(_configEndpoint, _defaultAzureCredential)
.Build();

// Assert
Assert.Equal("InitialValue1", config[$"{testContext.KeyPrefix}:Setting1"]);
Assert.Equal("InitialValue2", config[$"{testContext.KeyPrefix}:Setting2"]);
}

[Fact]
public async Task RefreshAsync_UpdatesConfiguration_WhenSentinelKeyChanged()
{
Expand Down
Loading