[英]Inject IOptions from array of sub-options to Service
I have a web service that posts data to a variety of different external servers, with a specific server to use specified by the incoming data to my API. New servers could be added at any time.我有一个 web 服务,该服务将数据发布到各种不同的外部服务器,并使用传入数据指定的特定服务器到我的 API。可以随时添加新服务器。
I have an appSettings.json like this:我有一个 appSettings.json 这样的:
"Settings": {
"SomeSetting1": "Value",
"SomeSetting2": "Value",
"ExternalServers": [
{
"Name": "ServerA",
"Address": "ServerAAddress"
},
...
{
"Name": "ServerZ",
"Address": "ServerZAddress"
},
]
}
With the following support classes:具有以下支持类:
public class MySettings {
public string SomeSetting1 { get; set; }
public string SomeSetting2 { get; set; }
public List<ExternalServerSettings> ExternalServers { get; set; }
}
public class ExternalServerSettings {
public string Name { get; set; }
public string Address { get; set; }
}
I am injecting the full Settings in Startup.cs:我在 Startup.cs 中注入完整的设置:
services.Configure<MySettings>(mySettings => Configuration.GetSection("Settings").Bind(mySettings));
I am creating a new service that I only want to inject an instance of ExternalServerSettings
.我正在创建一个新服务,我只想注入一个ExternalServerSettings
的实例。
Currently I am doing this:目前我正在这样做:
public class MyService : IMyService
{
private readonly ExternalServerSettings ServerSettings;
public MyService(ExternalServerSettings serverSettings) {
ServerSettings = serverSettings
}
}
In my controller or another service I will select the specific server based on inputs to the Post method.在我的 controller 或其他服务中,我将 select 基于对 Post 方法的输入的特定服务器。
But previously I have created other services which are injecting settings with IOptions
:但之前我已经创建了其他服务,这些服务正在使用IOptions
注入设置:
public OtherService(IOptions<MySettings> mySettings)
//instead of...
public OtherService(MySettings mySettings)
The existential crisis I am having is that I am creating MyService
knowing in advance that I would be selecting and injecting a specific object instead of using IOptions, but best practices dictate that I shouldn't know/care what is happening externally, and I would like to be able to create any Services consistently without worrying how they may be called.我遇到的生存危机是我在创建MyService
时事先知道我会选择并注入特定的 object 而不是使用 IOptions,但最佳实践规定我不应该知道/关心外部发生的事情,我会喜欢能够始终如一地创建任何服务,而不必担心它们的调用方式。 Is my pattern OK or is there a way to do this while still utilizing IOptions
?我的模式可以吗?还是有办法在仍然使用IOptions
的同时做到这一点?
I am very new C# web API and dependency injection, and I just want to make sure that I am following best practices for when I move to more complex projects.我是非常新的 C# web API 和依赖注入,我只是想确保在我转向更复杂的项目时遵循最佳实践。
Below is a work demo, you can refer to it.下面是一个工作演示,你可以参考它。
TopItemSettings TopItem设置
public class TopItemSettings
{
public const string Month = "Month";
public const string Year = "Year";
public string Name { get; set; }
public string Model { get; set; }
}
Put below into appsetting.json将下面放入appsetting.json
"TopItem": {
"Month": {
"Name": "Green Widget",
"Model": "GW46"
},
"Year": {
"Name": "Orange Gadget",
"Model": "OG35"
}
}
Register month in the startup在启动时注册月份
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<TopItemSettings>(TopItemSettings.Month,
Configuration.GetSection("TopItem:Month"));
//services.Configure<TopItemSettings>(TopItemSettings.Year,
// Configuration.GetSection("TopItem:Year"));
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "OPtions", Version = "v1" });
});
}
ValuesController值控制器
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly TopItemSettings _monthTopItem;
public ValuesController(IOptionsSnapshot<TopItemSettings> namedOptionsAccessor)
{
_monthTopItem = namedOptionsAccessor.Get(TopItemSettings.Month);
}
public ContentResult OnGet()
{
return Content($"Month:Name {_monthTopItem.Name} \n" +
$"Month:Model {_monthTopItem.Model} \n\n");
}
}
Result:结果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.