EF Custom Configuration Provider OnReload

Viewed 265

I'm going through the [Microsoft documentation][1] on implementing a Custom Configuration Provider and trying to make an Entity Framework configuration provider, but I'm having trouble understanding re-loading configuration.

The examples I have seen online are re-loading configuration based on changes being recorded, but I just want a simple re-load at some interval. Is this possible?

This is my Configuration Source:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
    {
        _optionsAction = optionsAction;
    }
    
    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new EFConfigurationProvider(_optionsAction);
    }
}

Configuration Provider:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }
    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<MyDBContext>();

        OptionsAction(builder);

        using (var dbContext = new MyDBContext(builder.Options))
        {
            Data = dbContext.SomeConfigurationTable.ToDictionary(x => x.ConfigCd, x => x.ConfigValue);
        }
    }
}

I'm adding it to my app configuration with an extension method:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(this IConfigurationBuilder builder, Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

Registering it:

public static IHostBuilder CreateHostBuilder(string[] args)
{
    ...
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        // Create a temporary IConfiguration to read in values needed on building the host.
        IConfiguration appConfig = new ConfigurationBuilder().AddJsonFile("appsettings.json", false, false).Build();

        config.AddEFConfiguration(options => options.UseSqlServer(appConfig.GetConnectionString("RTPConnection")));
    });
    
    ...
}

How do I implement the reload on change?

Reload-on-change isn't implemented, so updating the database after the app has started will not affect the app's configuration. [1]: https://docs.microsoft.com/en-us/dotnet/core/extensions/custom-configuration-provider

2 Answers

You can fix this problem by manually reloading the configurations.

 var root = configuration as IConfigurationRoot;
 var provider = root.Providers.FirstOrDefault(p => p is EFConfigurationProvider);
 provider.Load();

Note: If you are using IOptionMonitor or IOptionSnapshot, you should also call the OnReload() method in the load method after loading the data to trigger the OnChange event.

Related