IConfigureOptions<T> 没有创建作用域选项
IConfigureOptions<T> is not creating scoped options
通常 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
的实例,因此在 startup.cs
中将其注册为 Scoped
services.AddScoped<IConfigureOptions<MyOptions>, ConfigureMyOptions>();
但是,当我将调试器放入 ConfigureMyOptions 的 Configure 方法中时,它只会在第一次请求时被命中一次。对于下一个请求,容器 returns 相同的实例(如单例)。
如何在此处设置范围以便为每个请求创建 MyOptions?
在您的控制器中使用 IOptionsSnapshot
而不是 IOptions
,它将根据请求重新创建选项。
为什么不能与 IOptions
一起使用:
.AddOptions 配置 API 的扩展方法将 OptionsManager
实例注册为 IOptions<>
的单个实例
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>)));
services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>)));
和OptionsManager
class uses caching internally:
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 should always be recreated per request
通常 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
的实例,因此在 startup.cs
Scoped
services.AddScoped<IConfigureOptions<MyOptions>, ConfigureMyOptions>();
但是,当我将调试器放入 ConfigureMyOptions 的 Configure 方法中时,它只会在第一次请求时被命中一次。对于下一个请求,容器 returns 相同的实例(如单例)。
如何在此处设置范围以便为每个请求创建 MyOptions?
在您的控制器中使用 IOptionsSnapshot
而不是 IOptions
,它将根据请求重新创建选项。
为什么不能与 IOptions
一起使用:
.AddOptions 配置 API 的扩展方法将 OptionsManager
实例注册为 IOptions<>
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>)));
services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>)));
和OptionsManager
class uses caching internally:
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 should always be recreated per request