Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheritance with appsettings.json settings in .NET Core

I'm trying to achieve something like this:

  • BaseSettings - has settings common to all other sections
  • Child1Settings - has all BaseSettings + Child1Settings
  • Child2Settings - has all BaseSettings + Child2Settings

    [...]

  • ChildNSettings - has all BaseSettings + ChildNSettings

So then I'd have this in my controllers:

public class Child1Controller : Controller
{
    public Child1Controller(Child1Settings settings)
    {
        // settings.BaseSetting and settings.Child1Setting should both be accessible here
    }
}

I've tried this:

public class BaseSettings
{
    public string BaseSetting { get; set; }
}

public class Child1Settings : BaseSettings
{
    public string Child1Setting { get; set; }
}

appsettings.json

{
    "BaseSettings": {
        "BaseSetting": "BaseSettingValue"
    },
    "Child1Settings": {
        "Child1Setting": "Child1SettingValue"
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{    
    services.AddOptions();
    services.Configure<Child1Settings>(options => Configuration.GetSection("Child1Settings").Get<Child1Settings>());
    services.AddSingleton(Configuration);
}

That populates the Child1Settings fields just fine, but not the BaseSettings fields. I could see this working (though I haven't tried), but this feels ridiculous and would lead to a LOT of redundancy and potential error if I were to have many child setting classes:

appsettings.json

{
    "Child1Settings": {
        "BaseSettings": {
            "BaseSetting": "BaseSettingValue"
        }
        "Child1Setting": "Child1SettingValue"
    },
    "Child2Settings": {
        "BaseSettings": {
            "BaseSetting": "BaseSettingValue"
        }
        "Child2Setting": "Child2SettingValue"
    }
}
like image 589
jacobsowles Avatar asked Jul 19 '17 17:07

jacobsowles


1 Answers

One way to achieve this is by configure your child with base section data then configure it with child specific data like this:

services.Configure<Child1Settings>(hostContext.Configuration.GetSection("BaseSettings"));
services.Configure<Child1Settings>(hostContext.Configuration.GetSection("Child1Settings"));

This way the first call to Configure<Child1Settings> will configure it with base data. The next call to Configure<Child1Settings> will override what you have configured in the BaseSettings and add the additional Child1Settings to it.

like image 177
A.Bashar Eter Avatar answered Oct 10 '22 16:10

A.Bashar Eter