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
1 change: 1 addition & 0 deletions eng/.docsettings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ known_content_issues:
- ['sdk/extensions/Azure.Extensions.AspNetCore.DataProtection.Keys/README.md','azure-sdk-tools/issues/404']
- ['sdk/extensions/Microsoft.Azure.WebJobs.Extensions.Clients/README.md','azure-sdk-tools/issues/404']
- ['sdk/extensions/Microsoft.Extensions.Azure/README.md','azure-sdk-tools/issues/404']
- ['sdk/appconfiguration/Microsoft.Extensions.Configuration.AppConfiguration/README.md','azure-sdk-tools/issues/404']
- ['sdk/identity/Azure.Identity.Broker/README.md','azure-sdk-tools/issues/404']
- ['sdk/storage/Azure.Storage.Common/README.md','azure-sdk-tools/issues/404']
- ['sdk/textanalytics/Azure.AI.TextAnalytics.Legacy.Shared/README.md','https://github.com/Azure/azure-sdk-tools/issues/404']
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Release History

## 1.0.0-beta.1 (Unreleased)

### Features Added

- Initial release of `Microsoft.Extensions.Configuration.AppConfiguration`.
- Added `AddAppConfigurations` extension methods for `IConfigurationBuilder`.

### Breaking Changes

### Bugs Fixed

### Other Changes
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<IsClientLibrary>true</IsClientLibrary>
</PropertyGroup>

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.props))\Directory.Build.props" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Azure App Configuration provider for Microsoft.Extensions.Configuration

The `Microsoft.Extensions.Configuration.AppConfiguration` package allows storing configuration values using Azure App Configuration.

## Getting started

### Install the package

Install the package with NuGet:

```dotnetcli
dotnet add package Microsoft.Extensions.Configuration.AppConfiguration
```

### Prerequisites

You need an [Azure subscription][azure_sub] and an
[App Configuration store][appconfig_doc] to use this package.

To create a new App Configuration store, you can use the [Azure Portal][appconfig_create_portal],
[Azure PowerShell][appconfig_create_ps], or the [Azure CLI][appconfig_create_cli].
Here's an example using the Azure CLI:

```Powershell
az appconfig create --name MyAppConfig --resource-group MyResourceGroup --location westus
az appconfig kv set --name MyAppConfig --key MyKey --value "MyValue"
```

## Key concepts

### Thread safety
We guarantee that all client instance methods are thread-safe and independent of each other ([guideline](https://azure.github.io/azure-sdk/dotnet_introduction.html#dotnet-service-methods-thread-safety)). This ensures that the recommendation of reusing client instances is always safe, even across threads.

### Additional concepts
<!-- CLIENT COMMON BAR -->
[Client options](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/README.md#configuring-service-clients-using-clientoptions) |
[Accessing the response](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/README.md#accessing-http-response-details-using-responset) |
[Long-running operations](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/README.md#consuming-long-running-operations-using-operationt) |
[Handling failures](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/README.md#reporting-errors-requestfailedexception) |
[Diagnostics](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/samples/Diagnostics.md) |
[Mocking](https://learn.microsoft.com/dotnet/azure/sdk/unit-testing-mocking) |
[Client lifetime](https://devblogs.microsoft.com/azure-sdk/lifetime-management-and-thread-safety-guarantees-of-azure-sdk-net-clients/)
<!-- CLIENT COMMON BAR -->

## Examples

To load configuration from Azure App Configuration, first configure an `AppConfiguration` section in your `appsettings.json` that describes the `ConfigurationClient` to use. Settings stored in your App Configuration store — such as retry options — are merged into the configuration so that subsequent calls like `AddClient` can consume them.

For example, your local `appsettings.json` defines the client endpoint and credential, while retry settings like `MyClient:Options:Retry:MaxRetries` live in your App Configuration store:

```json
{
"AppConfiguration": {
"Endpoint": "https://myappconfig.azconfig.io",
"Credential": {
"CredentialSource": "AzureCliCredential"
}
},
"MyClient": {
"Endpoint": "https://myservice.example.com",
"Credential": {
"CredentialSource": "AzureCliCredential"
}
}
}
```

Then call `AddAppConfigurations` on the configuration builder, passing the name of the section that describes the `ConfigurationClient`. When the configuration is built, settings from your App Configuration store are loaded and merged with the local configuration:

```C# Snippet:ConfigurationAddAppConfigurations
HostApplicationBuilder builder = Host.CreateApplicationBuilder();
builder.Configuration.AddJsonFile("appsettings.json");
builder.Configuration.AddAppConfigurations("AppConfiguration");
builder.AddClient<MyClient, MyClientSettings>("MyClient");

IHost host = builder.Build();
MyClient client = host.Services.GetRequiredService<MyClient>();
```

The [Azure Identity library][identity] provides easy Azure Active Directory support for authentication.

## Next steps

Read more about [configuration in ASP.NET Core][aspnetcore_configuration_doc].

## Contributing

This project welcomes contributions and suggestions. Most contributions require
you to agree to a Contributor License Agreement (CLA) declaring that you have
the right to, and actually do, grant us the rights to use your contribution. For
details, visit [cla.microsoft.com][cla].

This project has adopted the [Microsoft Open Source Code of Conduct][coc].
For more information see the [Code of Conduct FAQ][coc_faq]
or contact [opencode@microsoft.com][coc_contact] with any
additional questions or comments.

<!-- LINKS -->
[source]: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/appconfiguration/Microsoft.Extensions.Configuration.AppConfiguration/src
[appconfig_create_cli]: https://learn.microsoft.com/azure/azure-app-configuration/quickstart-azure-app-configuration-create?tabs=azure-cli#create-an-app-configuration-store
[appconfig_create_portal]: https://learn.microsoft.com/azure/azure-app-configuration/quickstart-azure-app-configuration-create?tabs=azure-portal#create-an-app-configuration-store
[appconfig_create_ps]: https://learn.microsoft.com/azure/azure-app-configuration/quickstart-azure-app-configuration-create?tabs=azure-powershell#create-an-app-configuration-store
[azure_sub]: https://azure.microsoft.com/free/dotnet/
[identity]: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/identity/Azure.Identity/README.md
[aspnetcore_configuration_doc]: https://learn.microsoft.com/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1
[appconfig_doc]: https://learn.microsoft.com/azure/azure-app-configuration/overview
[cla]: https://cla.microsoft.com
[coc]: https://opensource.microsoft.com/codeofconduct/
[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/
[coc_contact]: mailto:opencode@microsoft.com
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Microsoft.Extensions.Configuration
{
[System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SCME0002")]
public static partial class AppConfigurationExtensions
{
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AddAppConfigurations(this Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder, string sectionName) { throw null; }
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AddAppConfigurations(this Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder, string sectionName, System.Action<Azure.Data.AppConfiguration.ConfigurationClientSettings> configureSettings) { throw null; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Microsoft.Extensions.Configuration
{
[System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SCME0002")]
public static partial class AppConfigurationExtensions
{
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AddAppConfigurations(this Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder, string sectionName) { throw null; }
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AddAppConfigurations(this Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder, string sectionName, System.Action<Azure.Data.AppConfiguration.ConfigurationClientSettings> configureSettings) { throw null; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Microsoft.Extensions.Configuration
{
public static partial class AppConfigurationExtensions
{
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AddAppConfigurations(this Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder, string sectionName) { throw null; }
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AddAppConfigurations(this Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder, string sectionName, System.Action<Azure.Data.AppConfiguration.ConfigurationClientSettings> configureSettings) { throw null; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Diagnostics.CodeAnalysis;
using Azure.Data.AppConfiguration;
using Azure.Identity;
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using Azure.Identity; is unused in this file. Since warnings are treated as errors, this will fail the build; remove the unused using (the package reference can remain).

Suggested change
using Azure.Identity;

Copilot uses AI. Check for mistakes.
using Microsoft.Extensions.Configuration.AppConfiguration;

namespace Microsoft.Extensions.Configuration
{
/// <summary>
/// Extension methods for registering <see cref="AppConfigurationProvider"/> with <see cref="IConfigurationBuilder"/>.
/// </summary>
[Experimental("SCME0002")]
public static class AppConfigurationExtensions
{
/// <summary>
/// Adds an <see cref="IConfigurationProvider"/> that reads configuration values from Azure App Configuration.
/// The <see cref="ConfigurationClient"/> is created from the specified configuration section using
/// <see cref="ConfigurationClientSettings"/>.
/// </summary>
/// <param name="configurationBuilder">The <see cref="IConfigurationBuilder"/> to add to.</param>
/// <param name="sectionName">The name of the configuration section that contains the <see cref="ConfigurationClientSettings"/>.</param>
/// <returns>The <see cref="IConfigurationBuilder"/>.</returns>
public static IConfigurationBuilder AddAppConfigurations(
this IConfigurationBuilder configurationBuilder,
string sectionName)
{
return AddAppConfigurations(configurationBuilder, sectionName, null);
}

/// <summary>
/// Adds an <see cref="IConfigurationProvider"/> that reads configuration values from Azure App Configuration.
/// The <see cref="ConfigurationClient"/> is created from the specified configuration section using
/// <see cref="ConfigurationClientSettings"/>. The <paramref name="configureSettings"/> callback can be used
/// to modify the settings before the client is created.
/// </summary>
/// <param name="configurationBuilder">The <see cref="IConfigurationBuilder"/> to add to.</param>
/// <param name="sectionName">The name of the configuration section that contains the <see cref="ConfigurationClientSettings"/>.</param>
/// <param name="configureSettings">An optional callback to configure the <see cref="ConfigurationClientSettings"/> before the client is created.</param>
/// <returns>The <see cref="IConfigurationBuilder"/>.</returns>
public static IConfigurationBuilder AddAppConfigurations(
this IConfigurationBuilder configurationBuilder,
string sectionName,
Action<ConfigurationClientSettings> configureSettings)
{
if (configurationBuilder == null)
{
throw new ArgumentNullException(nameof(configurationBuilder));
}
if (string.IsNullOrEmpty(sectionName))
{
throw new ArgumentException("Value cannot be null or empty.", nameof(sectionName));
}

IConfiguration configuration = configurationBuilder.Build();
ConfigurationClientSettings settings = configuration.GetAzureClientSettings<ConfigurationClientSettings>(sectionName);
configureSettings?.Invoke(settings);

ConfigurationClient client = new ConfigurationClient(settings);
configurationBuilder.Add(new AppConfigurationSource(client, new AppConfigurationOptions()));

return configurationBuilder;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using Azure.Data.AppConfiguration;

namespace Microsoft.Extensions.Configuration.AppConfiguration
{
/// <summary>
/// Options class used by the <see cref="AppConfigurationExtensions"/>.
/// </summary>
internal class AppConfigurationOptions
{
/// <summary>
/// Creates a new instance of <see cref="AppConfigurationOptions"/>.
/// </summary>
public AppConfigurationOptions()
{
Manager = AppConfigurationSettingManager.Instance;
}

/// <summary>
/// Gets or sets the <see cref="AppConfigurationSettingManager"/> instance used to control setting loading.
/// </summary>
public AppConfigurationSettingManager Manager { get; set; }

/// <summary>
/// Gets or sets the timespan to wait between attempts at polling Azure App Configuration for changes. <code>null</code> to disable reloading.
/// </summary>
public TimeSpan? ReloadInterval { get; set; }

/// <summary>
/// Gets or sets the <see cref="SettingSelector"/> used to filter which configuration settings are loaded. <code>null</code> to load all settings.
/// </summary>
public SettingSelector Selector { get; set; }
}
}
Loading
Loading