c# - 在 ASP.NET Core 中通过依赖注入(inject)注册后,如何修改选项对象(保存配置设置)中的值?

标签 c# asp.net-core dependency-injection .net-core-3.1

我有一个方法,是不同类中的许多方法之一,如下所示,在 .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/

相关文章:

c# - Auto Mapper Profiler Class 放置在哪个文件夹中?

c# - .net 中的提供商模型

c# - 从对象运行时隐式转换

c# - 如何 : Execute command line in C#, 获取 STD OUT 结果

Azure 前门 - 并非所有节点都处于负载平衡状态

asp.net-core - ASP.NET vNext - 本地化 (.resx)

c# - 如何在 .net 核心 JwtBearerOptions.Events 中使用依赖注入(inject)?

java - maven 缺少 Artifact javax.transaction :jta:jar:1. 0.1B

c# - 异步函数陷入死锁?

java - 如何为 Spring 测试配置嵌套依赖?