asp.net 使用appsettings继承,json设置,NET核心

wko9yo5t  于 2023-05-02  发布在  .NET
关注(0)|答案(2)|浏览(147)

我正在努力实现这样的目标:

  • BaseSettings -具有所有其他部分通用的设置
  • Child 1 Settings-具有所有BaseSettings + Child 1 Settings
  • Child 2Settings-具有所有BaseSettings + Child 2Settings

[...]

  • ChildNSettings -具有所有BaseSettings + ChildNSettings

所以我在我的控制器里有这个:

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

我试过这个:

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);
}

这可以很好地填充Child 1 Settings字段,但不能填充BaseSettings字段。我可以看到这个工作(虽然我没有尝试过),但这感觉很荒谬,如果我有很多孩子设置类,会导致很多冗余和潜在的错误:

appsettings.json

{
    "Child1Settings": {
        "BaseSettings": {
            "BaseSetting": "BaseSettingValue"
        }
        "Child1Setting": "Child1SettingValue"
    },
    "Child2Settings": {
        "BaseSettings": {
            "BaseSetting": "BaseSettingValue"
        }
        "Child2Setting": "Child2SettingValue"
    }
}
eaf3rand

eaf3rand1#

实现此目的的一种方法是使用基本部分数据配置子对象,然后使用子对象特定的数据配置它,如下所示:

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

这样,对Configure<Child1Settings>的第一次调用将用基本数据配置它。对Configure<Child1Settings>的下一次调用将覆盖您在BaseSettings中配置的内容,并向其中添加额外的Child1Settings。

mrfwxfqh

mrfwxfqh2#

因为Child1Settings是一个子类,所以它包含了基类的所有属性。试试这个:

appsettings.json

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

保持Startup.cs原样:

Startup.cs

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

这将允许您在控制器中同时使用settings.BaseSettingsettings.Child1Setting。它还允许您为每个子节点指定单独的BaseSettings
话虽如此,我个人会避免这种设置,因为它使事情复杂化。当您查看Child1Settings类时,您无法立即判断哪些设置可用,您必须遵循继承路径。为了避免这种情况,您可以将BaseSettings更改为ChildSettings类需要实现的接口(IBaseSettings)。这可确保所有子类都包括基本设置,但强制您重复每个子类中的所有设置,以便始终可以直接查看每个部分中可用的设置。
另一方面,如果您希望有一个通用的BaseSettings部分,则根本不需要继承。只需在控制器构造函数中注入BaseSettingsChild1Settings

相关问题