Dot-Net-Core
IConfigureOptions<T> 沒有創建範圍選項
通常
Options是單例。但是我正在從數據庫中建構選項,其中一個選項屬性是密碼,每個月都在變化。所以我想創建Scoped選項的實例。我正在使用IConfigureOptions<T>如下方式從數據庫建構選項public class MyOptions { public string UserID {get;set;} public string Password {get;set; } public class ConfigureMyOptions : IConfigureOptions<MyOptions> { private readonly IServiceScopeFactory _serviceScopeFactory; public ConfigureMyOptions(IServiceScopeFactory serviceScopeFactory) { _serviceScopeFactory = serviceScopeFactory; } public void Configure(MyOptions options) { using (var scope = _serviceScopeFactory.CreateScope()) { var provider = scope.ServiceProvider; using (var dbContext = provider.GetRequiredService<MyDBContext>()) { options.Configuration = dbContext.MyOptions .SingleOrDefault() .Select(x => new MyOptions() { UserID = x.UserID, Password = x.Password }); } } } }在控制器中使用它
public class HomeController : BaseController { private readonly MyOptions _options; public HomeController(IOptions<MyOptions> option) { _options = option.Value; } [HttpGet] [Route("home/getvalue")] public string GetValue() { // do something with _options here return "Success"; } }我想
MyOptions為每個新請求創建一個實例,因此將其註冊為Scoped在 startup.csservices.AddScoped<IConfigureOptions<MyOptions>, ConfigureMyOptions>();但是,當我將調試器放在 ConfigureMyOptions 的 Configure 方法中時,它只會在第一個請求中被命中一次。對於下一個請求,容器返回相同的實例(如單例)。
如何在此處設置範圍,以便為每個請求創建 MyOptions?
在您的控制器中使用
IOptionsSnapshot而不是,IOptions它將根據請求重新創建選項。為什麼不適用於
IOptions:Configuration API 的.AddOptions擴展方法將
OptionsManager實例註冊為單例IOptions<>services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>))); services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>)));和
OptionsManager類在內部使用記憶體:public virtual TOptions Get(string name) { name = name ?? Options.DefaultName; // Store the options in our instance cache return _cache.GetOrAdd(name, () => _factory.Create(name)); }github 上的以下問題有助於在上面找到:OptionsSnapshot 應該始終根據請求重新創建