Questions › 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.


1 Answers :
Victor Hurdugaci answered

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/359

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.

Andy Palmer replied
As a caution, an interface doesn't actually buy you immutability, since it can easily be cast away. One, not particularly obscure, corner of C# where you can do this without thinking is in the variable declaration of a foreach loop. OTOH, you're not very likely to have IEnumerable<Config>. It's all how well you want to sleep at night.;