Azure / Azure/AppConfiguration-DotnetProvider
Support custom IConfigurationRefresher implementations in AzureAppConfigurationRefresherProvider
- Dominant language
- C#
- Stars
- 93
- Forks
- 46
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 3
Description
Hi!
We're trying to add Azure App Configuration sources with a priority lower than the default `appsettings.{Environment}.json` file's one, using `WebApplicationBuilder`.
We noticed that `WebApplicationBuilder`'s behavior is to trigger a reload of all sources in `Configuration.Sources` every time the collection is modified in any way other than with `Add` (e.g., with `Insert`).
Loading the configuration from AAC more than once is problematic as it can take a lot of time, especially when some configuration keys link to Azure Key Vaults. Doing this work several times impacts negatively the startup time of an application that uses `WebApplicationBuilder`.
We already opened an [issue](https://github.com/dotnet/runtime/issues/123188) about this behavior in the ASP.NET Core repo, but we thought that in the meantime, we could shield the Azure App Configuration source/provider from those reloads by registering our one decorator implementation of `IConfigurationSource`/`IConfigurationProvider`/`IConfigurationRefresher`.
However, as soon as we try to use AAC's dynamic configuration middleware (with `UseAzureAppConfiguration`), we get an `InvalidOperationException` from this [code](https://github.com/Azure/AppConfiguration-DotnetProvider/blob/34576ef70d303a029b7ea7ef860f12885fb8f35d/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationRefresherProvider.cs#L52-L55):
```csharp
if (!refreshers.Any())
{
throw new InvalidOperationException("Unable to access the Azure App Configuration provider. Please ensure that it has been configured correctly.");
}
```
Despite the interfaces being public, the method `FindRefreshers` of [`AzureAppConfigurationRefresherProvider`](https://github.com/Azure/AppConfiguration-DotnetProvider/blob/34576ef70d303a029b7ea7ef860f12885fb8f35d/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationRefresherProvider.cs) still expects the implementation of all `configurationRoot.Providers` to be of the `AzureAppConfigurationProvider` internal type (probably to be able to set the logger factory via the `LoggerFactory` property, which is not part of the [`IConfigurationRefresher`](https://github.com/Azure/AppConfiguration-DotnetProvider/blob/34576ef70d303a029b7ea7ef860f12885fb8f35d/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/IConfigurationRefresher.cs) interface).
```csharp
if (provider is AzureAppConfigurationProvider appConfigurationProvider)
{
appConfigurationProvider.LoggerFactory = loggerFactory;
refreshers.Add(appConfigurationProvider);
}
```
This prevents us to use `AzureAppConfigurationRefresherProvider` with our own implementation of `IConfigurationProvider`/`IConfigurationRefresher`.
We could implement our own `IConfigurationRefresherProvider` (and thus duplicate the logic of `AzureAppConfigurationRefresherProvider`) in order to support our other custom implementations, but it is not ideal.
Would it be possible to stop locking `AzureAppConfigurationRefresherProvider` to a specific implementation of `IConfigurationRefresher` (possibly by promoting the `LoggerFactory` property to the `IConfigurationRefresher` interface)?
Thanks a lot for your consideration.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.