Skip to content

Support custom IConfigurationRefresher implementations in AzureAppConfigurationRefresherProvider #713

@Nechepso

Description

@Nechepso

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 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:

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 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 interface).

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.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions