我有一个方法,是不同类中的许多方法之一,如下所示,在 .NET 类中,该方法使用连接字符串、选项对象(选项模式)中的属性,名为 DBOptions
,它被注入(inject)到类中。
DBOptions 在应用程序启动期间使用 services.Configure<DBOptions>()
在 DI 中注册.
DBOptions
在应用程序启动期间配置为使用 appsettings.json 中的特定命名连接字符串。
现在需要在运行时有条件地使用另一个连接字符串。这是用户在 UI 中选择的每个 Web 请求。我在 appsettings.json 中添加了第二个命名连接字符串。
由于当前在应用程序启动期间 DBoptions 设置为使用特定的命名连接字符串,因此在 DI 在类中注入(inject) DBOptions 之前,如何在运行时在两个连接字符串之间切换?或者如何在将 DBOptions 连接字符串注入(inject)任何使用它的类之前更新它?据我所知,当源(appsettings.json 文件)被修改时,IOptionsSnapshot 会重新加载选项,但这不是我的情况。
应用未使用 EFCore。
public class Books
{
private readonly string connectionString;
public Books(IOptions<DBOptions> options)
{
this.connectionString = options.Value.connectionString; //<-- value needs to be set conditionally
//outside of any class that uses DBoptions
}
public void SomeMethod()
{
.... //uses connectionString
}
}
最佳答案
由于您表示选项将取决于请求,因此您可以访问 IHttpContextAccessor
并从请求中提取设置所需成员所需的条件。
这是一个过于简单的示例
//...
services.AddOptions<DBOptions>()
.Configure<IHttpContextAccessor, IConfiguration>(
(options, http, config) => {
HttpContext context = http.Current;
HttpRequest request = context.Request;
if({/*some condition based on request...*/}) {
options.connectionString = config.GetConnectionString("name1");
} else {
options.connectionString = config.GetConnectionString("name2");
}
//...etc
};
//...
引用:Use DI services to configure options .
或者放弃与框架的选项模式的紧密耦合,并直接将您的类注册为 transient 或作用域,因为它是基于每个 HTTP 请求创建的
//...
services.AddTransient<DBOptions>(sp => {
IHttpContextAccessor http = sp.GetRequiredService<IHttpContextAccessor>();
IConfiguration config = sp.GetRequiredService<IConfiguration>();
HttpContext context = http.Current;
HttpRequest request = context.Request;
DBOptions options = new DBOptions() {
//populate as needed or extract from configuration
}
if({/*some condition based on request...*/}) {
options.connectionString = config.GetConnectionString("name1");
} else {
options.connectionString = config.GetConnectionString("name2");
}
//...etc
return options;
});
//...
但是,这需要依赖类显式依赖 DBOptions
而不是紧密耦合到 IOptions<DBOptions>
public class Books {
private readonly string connectionString;
public Books(DBOptions options) {
this.connectionString = options.connectionString;
}
public void SomeMethod() {
//... uses connectionString
}
}
关于c# - 在 ASP.NET Core 中通过依赖注入(inject)注册后,如何修改选项对象(保存配置设置)中的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71258000/