在嵌套类中使用配置设置

时间:2019-02-07 11:18:06

标签: c# dependency-injection appsettings

当我在孩子需要一些配置设置的嵌套类(即用appsettings.json编写的设置)中嵌套嵌套时,是否需要进行存储桶中继以将配置传递给孩子类?

我认为以下示例不是明智的方法。有更好的做法吗?

Startup.cs

public Startup(IConfiguration configuration, ...)
    {
        ...
        this.Configuration = configuration;
        ...
    }

Parent.cs

public class Parent
{
    public Parent(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    private IConfiguration _configuration;
    private ChildOne _childOne;
    private ChildTwo _childTwo;

    public void InitializeChildren()
    {
        _childOne = new ChildOne(_configuration);
        _childTwo = new ChildTwo(_configuration);
    }
}

ChildOne.cs

public class ChildOne{
    public ChildOne(IConfiguration configuration){
        _propOne = configuration.GetSection("brahbrah").Value;
    }

    private string _propOne;
}

2 个答案:

答案 0 :(得分:1)

域对象/模型只不过是数据容器。这些数据容器可能需要数据,但不应依赖于(直接)对此数据进行依赖注入,因为它们是应用程序的核心。模型中的更改(或其依赖性)很可能会导致更大的更改。

如示例所示,您想使用new运算符实例化模型,并将IConfiguration作为参数传递。通过在数据容器中要求IConfiguration,您将创建一种情况,您的模型将需要大量检查返回的结果是否存在以及其中的每个属性是否存在,然后在数据容器中设置适当的值。

对此问题的更好解决方案是在依赖项注入框架中注册专用的config类,我们将其称为BrahBrahConfig以匹配您的示例。

public static IServiceCollection SetupDependencyInjection(this 
    IServiceCollection services, IConfiguration config)
{
    services.Configure<BrahBrahConfig>(config.GetSection("brahbrah"));

    return services;
}

在上面的示例中,您看到IServiceCollection Configure<TOptions>(this IServiceCollection services, IConfiguration config)使用了重载,可以在nuget包“ Microsoft.Extensions.Options.ConfigurationExtensions”中找到该重载。

此重载使您可以将IOptions实例直接注入到您选择的构造函数中。

private BrahBrahConfig _config;

public Parent(IOptions<BrahBrahConfig> config)
{
    _config = config?.Value ?? throw new ArgumentNullException(nameof(config));
}

因此,在您的startup.cs中注册它之后,可以将IOptions用作Parent构造函数中的参数,并使用这些设置来设置模型中的适当属性。

答案 1 :(得分:1)

对您的服务而不是模型使用依赖项注入。模型不应具有任何逻辑或服务注册。

如果您在谈论服务类,那么它们通常是DI的一部分。您可以将它们注册到DI,以便DI在实例构建时自动解析服务。

例如,

public class Parent
{
    public Parent(IConfiguration configuration, ChildOne childOne, ChildTwo childTwo)
    {
        _configuration = configuration;
        _childOne = childOne;
        _childTwo = childTwo;
    }

    private IConfiguration _configuration;
    private ChildOne _childOne;
    private ChildTwo _childTwo;

}

如果您需要自己初始化ChildOne和ChildTwo,则需要传递IConfiguration参数或至少IServiceProvider以便解析所需的服务