Search code examples
c#.net-coredependency-injectionazure-app-configuration

How to use configuration data when configuring services in .Net 5.0?


I'm trying to use already configured custom config-class to configure another service. Configuration gets data from local settings and Azure AppConfiguration store. This is my Startup code:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAzureAppConfiguration();
    services.Configure<CustomConfig>(Configuration);

    services.AddTransient<ISomeService, SomeService>((serviceProvider) => 
        {
            CustomConfig config = serviceProvider.GetRequiredService<IOptions<CustomConfig>>().Value;
            return new SomeService(config);
        });
    //--------------------------------------------------------------------
    services.AddRazorPages();
    services.AddControllers();
}

But when SomeService is instantiated, my custom config-object doesn't contain data that should come from the Azure AppConfig. It has only data from the appsettings.json. What is wrong and what can I do here?


Solution

  • So the short answer is: it's actually working. I was suspecting some stupid error, and it was exactly the case (a couple of code lines was commented so data was not retrieved from Azure - shame on me).

    Thank you @pinkfloydx33 for the reassurance that the pattern should work.

    And in case if someone wonders about binding root config values - it works as well. In my case, appsettings.json contains root values that I need to connect to Azure AppConfig store (primary and secondary endpoints, refresh interval and environment name which is used in key labels) and a few sections corresponding with external services: database, AAD B2C etc which are retrieved from Azure AppConfig. So my custom class has root values and a few nested classes like this:

    public class CustomConfig : ConfigRoot
    {
        // These root values come from appsettings.json or environment variables in Azure
        [IsRequired]
        public string Env { get; set; }
    
        [IsRequired, Regex("RegexAppConfigEndpoint")]
        public Uri AppConfigEndpointPrimary { get; set; }
    
        [IsRequired, Regex("RegexAppConfigEndpoint")]
        public Uri AppConfigEndpointSecondary { get; set; }
    
        public int AppConfigRefreshTimeoutMinutes { get; set; } = 30;
    
        // And these sections come from the Azure AppConfig(s) from the above
        public ConfigSectionDb Db { get; set; } = new ConfigSectionDb();
    
        public ConfigSectionB2c B2c { get; set; } = new ConfigSectionB2c();
        
        // Some other sections here...
    }
    

    Here ConfigSection<...> classes contain in their turn other subclasses. So I have quite a hierarchy here. ConfigRoot here is an abstract class providing Validate method.

    And it works: this services.Configure<CustomConfig>(Configuration); part gets all the data - the root and the sections from all configured providers. In my case, it's two Azure AppConfigs, appsettings.json, environment variables.