在嵌套 类 中使用配置设置

Using configuration settings in nested classes

当我嵌套了类,其中children需要一些配置设置(即写在appsettings.json中的设置),我是否需要做一个bucket relay来传递配置到 children 类?

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

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

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

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

解决此问题的更好方法是在依赖注入框架中注册一个专用配置 class,我们将调用它来匹配您的示例。

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 构造函数中的参数,并使用这些设置在您的模型中设置适当的属性。

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

如果您谈论的是服务 类,它们通常是 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来解析所需的服务