我有一个 .Net 5 Web Api 项目,想要用一些逻辑配置选项。这就是为什么我想把配置从 Startup.ConfigureServices
方法中移出来,并将它们放到它们自己的服务配置器中(在启动时运行)。所以我想到了这个:
class OptionsConfigurator : IHostedService
{
private readonly IServiceCollection _serviceCollection;
public StartupOptionsConfigurator(IServiceCollection serviceCollection)
{
_serviceCollection = serviceCollection;
}
public Task StartAsync(CancellationToken cancellationToken)
{
/*
Build the ServiceProvider from the _serviceCollection
Get the IConfiguration service from the ServiceProvider
Read the configurationSection from the IConfiguration
call _serviceCollection.Configure<MyOptions>(configurationSection);
*/
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
由于我无法将IServiceCollection
注入到构造函数中,因此这种方法行不通。是否有一种方法可以在不需要 IServiceCollection
实例的情况下配置这些选项?
我可以提供另一个示例来说明问题:
您的 API 提供一个单一的端点来更新特定配置,以便在运行时更改它(例如,可能更改某些原因导致的数据库连接字符串)。
- 创建一个新的 Web API 项目
- 创建一个选项类
.
public class MyOptions
{
public string Text { get; set; }
}
- 创建一个控制器
.
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
private readonly IOptionsMonitor<MyOptions> _myOptionsMonitor;
private readonly IServiceCollection _serviceCollection;
public MyController(IOptionsMonitor<MyOptions> myOptionsMonitor, IServiceCollection serviceCollection)
{
_myOptionsMonitor = myOptionsMonitor;
_serviceCollection = serviceCollection;
}
[HttpPatch]
public IActionResult UpdateOptions([FromBody] string text)
{
Console.WriteLine("Before: " + JsonSerializer.Serialize(_myOptionsMonitor.CurrentValue));
_serviceCollection.Configure<MyOptions>(x => { x.Text = text; });
string newConfig = JsonSerializer.Serialize(_myOptionsMonitor.CurrentValue);
Console.WriteLine("After: " + newConfig);
return Ok(newConfig);
}
}
在请求正文中使用新的配置字符串调用补丁(endpoint)端点。如预期的那样,这也无法正常工作,注入IServiceCollection
无法实现并引发异常。
是否有任何解决方案以后再配置选项?