29

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?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Bogey
  • 4,926
  • 4
  • 32
  • 57

4 Answers4

26

For .Net Core 2.2, you need to modify Program.cs:

Before

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
           .UseStartup<Startup>();

After

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)

            //This is how you attach additional JSON files
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("customSettings.json", optional: false, reloadOnChange: false);
            })
            //End of update
            .UseStartup<Startup>();

For the latest amendments and to add other kinds of custom settings, please refer to Microsoft documentation at the following article.

Shadi Alnamrouti
  • 11,796
  • 4
  • 56
  • 54
  • This implementation works great, other implementations are causing problems with db migration commands. – LazZiya Nov 06 '20 at 07:36
22

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.

jpgrassi
  • 5,482
  • 2
  • 36
  • 55
13

As of ASP.NET Core 5.0 it is as simple as adding a call to ConfigureAppConfiguration() in the call to CreateDefaultBuilder(args) inside Program.cs like so:

From

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });

to

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("CustomSettings.json", optional: false, reloadOnChange: false);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
user2768479
  • 716
  • 1
  • 10
  • 25
5

As of .Net Core 6,

If you are using .NET 6 minimal hosting model, in the Program.cs add the following line after var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("CustomSettings.json", optional: false, reloadOnChange: false);

If you are still using .Net 5 startup style,change the CreateHostBuilder method in Program.cs file to the following:

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("CustomSettings.json", optional: false, reloadOnChange: false);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
Amir
  • 1,722
  • 22
  • 20
  • 1
    This was super helpful. I'm working in an app that must have started out as .NET 5 and was migrated to .NET 6 because the CreateHostBuilder method is how its configured. – Mike Mar 31 '23 at 01:04