Search code examples
c#asp.net-coreautofac

How can I add a custom JSON file into IConfiguration?


I'm using asp.net + Autofac.

I'm trying to load a custom JSON configuration file, and either create/instance an IConfiguration instance based on that, or at least include my file into whatever IConfiguration asp.net builds by default.

My problem is that asp.net seems to override the dependency registration for IConfiguration.

I can't seem to register my own IConfiguration object - the DI container will always resolve this to some instance that seems to have been generated by the asp.net library itself.

And I'm not sure how I can get asp.net to at least load my custom config file additionally - i.e. if there is any way to get a hold of the ConfigurationBuilder it uses, and add my own file before it is building the IConfiguration object.

I've tried the following:

public class Startup
{
    public IConfigurationRoot Configuration { get; }

    public Startup(IHostingEnvironment env)
    {
        this.Configuration = new ConfigurationBuilder()
            .SetBasePath(path)
            .AddJsonFile("somefile.json")
            .Build();
    }

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services
          .AddMvc()
          .AddControllersAsServices();

         var builder = new ContainerBuilder();
         builder.Register(x => this.Configuration).As<IConfiguration>();
         builder.Populate(services);

         var container = builder.Build();

         // This will return another IConfiguration instance then the one I registered; 
         // namely One that contains 1 provider, a MemoryConfigurationProvider
         var xxx = container.Resolve<IConfiguration>();

         return new AutofacServiceProvider(container);
    }
}

How can I get asp.net to load my custom JSON config file as well?


Solution

  • You can do this by using the Options pattern:

    On ASP.NET Core 2, register the config file on Program.cs

    public class Program
    {
        public static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    
                 // custom config file
                .AddJsonFile("myappconfig.json", optional: false, reloadOnChange: false)
                .Build();
    
            BuildWebHost(args, configuration).Run();
        }
    
        public static IWebHost BuildWebHost(string[] args, IConfiguration config) =>
            WebHost.CreateDefaultBuilder(args)
                .UseConfiguration(config)
                .UseStartup<Startup>()
                .Build();
    }
    

    Create a class that matches with your config file:

    public class MyAppConfig
    {
        public string SomeConfig { get; set; }
    
        public int NumberConfig { get; set; }
    }
    

    Register it on ConfigureServices

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    
        services.Configure<MyAppConfig>(Configuration);
    }
    

    Then, just access it in your Controller:

    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        private readonly MyAppConfig _appConfig;
    
        public ValuesController(IOptions<MyAppConfig> optionsAccessor)
        {
            if (optionsAccessor == null) throw new ArgumentNullException(nameof(optionsAccessor));
            _appConfig = optionsAccessor.Value;
        }
    
        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return _appConfig.SomeConfig;
        }
    }
    

    If you are not in ASP.NET Core 2 yet, the process is almost the same. You just need to add the custom config file on Startup.cs. The rest is basically the same.