在嵌套 类 中使用配置设置
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来解析所需的服务
当我嵌套了类,其中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来解析所需的服务