Search code examples
asp.netasp.net-mvcasp.net-coreconfigurationmanager

ASP.NET 5 (i.e. Core 1.0) Immutable Configuration


I can't get ASP.NET 5 (i.e. Core 1.0) to work with immutable configuration classes.

Let me demonstrate first using a mutable class.

config.json

{
  "Name": "Lou",
  "Age": 30
}

Config.cs (mutable)

   public class Config
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

Registration in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    var configBuilder = new ConfigurationBuilder()
        .AddJsonFile("config.json");

    var config = configBuilder.Build();
    services.Configure<Config>(config);

    services.AddMvc();
}

The code above works well and the values of Config.Name and Config.Age are as expected.

But once I change Config's property setters to private, they are no longer set by the configuration builder:

public class Config
{
    public string Name { get; private set; } // == null
    public int Age { get; private set; } // == 0
}

I would have expected ASP.NET 5 to use reflection and set the properties like it does with ASP.NET 4, instead of simply ignoring them. Am I missing something?

I created a sample project to demonstrate: https://github.com/johnnyoshika/mvc6-immutable-config The master branch uses a mutable Config class while the immutable-config branch uses an immutable Config class.


Solution

  • The ConfigurationBinder object doesn't set private properties: https://github.com/aspnet/Configuration/blob/ba1d9b4cbc363db9318f201f08fbfecc72e7922b/src/Microsoft.Extensions.Configuration.Binder/ConfigurationBinder.cs#L64-L82

    Here's an issue tracking that: https://github.com/aspnet/Configuration/issues/394

    One way to workaround this is to create an interface with getters only that's implemented by your Config code. Then, you can use that in your code.