Search code examples
configurationasp.net-core.net-coreconfiguration-files

Access linked files configuration files - or how to reach the output directory


We have a sln with basically the following structure

Sln
 |--MyApp.Lib
 |     |-- LotsOfCode
 |--MyApp.Web (old)
 |     |-- SetParameters.DEV.xml
 |     |-- SetParameters.TEST.xml
 |     |-- SetParameters.PROD.xml
 |--MyApp.API (net core)
       |-- appsettings.json
       |-- SetParameters.DEV.xml 
       |-- SetParameters.TEST.xml (link)
       |-- SetParameters.PROD.xml (link)

We would like to reuse the settings file in the API project. I've created a custom ConfigurationProvider that can read the SetParameters files, but I'm unable to get it to run when I add the files as link.

Problem: When I add a file as link (and set type=Content) it gets copied to the output directory, and I can't seem to figure out a safe way to get that file. Then IHostinEnvironment don't seem to know what a Output or bin directory is.

Any ideas?


Solution

  • IHostingEnvironment environment has WebRootPath property, which can be used for reading local files like this:

    using System.IO;
    
    IHostingEnvironment _env;
    
    var pathToFile = Path.Combine(_env.WebRootPath, "SetParameters.TEST.xml"));
    var settings = File.ReadAllLines(pathToFile);
    

    However, in ASP.NET Core you have an opportunity to bind your settings with ConfigurationBuilder. In a given article one can see JSON file usage, however, you can use AddXmlFile too. It will be like:

    var builder = new ConfigurationBuilder()
         // set current output path as root
         .SetBasePath(env.ContentRootPath)
         // EnvironmentName can be DEV, TEST, PROD, etc
         .AddXmlFile($"SetParameters.{env.EnvironmentName}.xml");
    
    IConfigurationRoot configuration = builder.Build();
    

    After that you can access your parameters like this, given your sample xml:

    <parameters>
        <settings>
          <param1 name="Test" value="val" />
        </settings>
    </parameters>
    
    // will be "val"
    configuration["Parameters:param1:value"]
    

    I found great article regarding legacy apps configuration in ASP.NET core. Other option, more object-oriented, is to bind your parameters to a model class, as described in MSDN article.