【问题标题】:How can I add a dbContext after Startup in .Net Core?如何在 .Net Core 中启动后添加 dbContext?
【发布时间】:2019-05-25 03:39:05
【问题描述】:

我正在使用 .Net Core,使用内置的依赖注入。在我的登录屏幕中,我还需要用户选择一个部门数据库——我们有不同的数据库具有相同的结构,以使用具有不同数据的相同应用程序。但是,我不知道如何添加/修改 dbContext 这么晚。 Startup.cs 有 DI,但在用户选择部门之前,我不知道要从配置中读取哪个连接字符串。是小型数据库,公司不关心重复数据库的管理。

如何延迟添加服务

services.AddDbContext<my_accountingContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("CorrectDepartmentConfig")));

当我真正知道什么是 CorrectDepartmentConfig 时?

或者,如果无法做到这一点,我该如何在 Startup.cs 之后对 my_accountingContext 进行臭名昭著的更改?

【问题讨论】:

标签: c# dependency-injection .net-core


【解决方案1】:

您可以在 Startup 类的 ConfigureServices 方法中使用 IServiceCollection 的实现工厂重载:

//First register a custom made db context provider
services.AddTransient<ApplicationDbContextFactory>();
//Then use implementation factory to get the one you need
services.AddTransient(provider => provider.GetService<ApplicationDbContextFactory>().CreateApplicationDbContext());

CreateApplicationDbContext 的实现完全取决于您想要什么,但该方法的基本内容应如下所示:

public ApplicationDbContext CreateApplicationDbContext(){
  //TODO Something clever to create correct ApplicationDbContext with ConnectionString you need.
} 

一旦实现,您就可以在控制器中注入正确的 ApplicationDbContext,操作...

public MyController(ApplicationDbContext dbContext)
{
    _dbContext = dbContext;
}

public IActionResult([FromServices] ApplicationDbContext dbContext){
}

【讨论】:

    【解决方案2】:

    您始终可以从受保护的 OnConfiguring 方法中设置连接字符串。您可以从那里访问 IConfiguration 实例(DbContext 类有一个服务定位器,Instance 属性),检索连接字符串,然后使用适当的连接调用 UseMySql 扩展方法。

    类似这样的:

    protected virtual void OnConfiguring(DbContextOptionsBuilder builder)
    {
        var configuration = (this as IInfrastructure<IServiceProvider>).GetService<IConfiguration>();
        var connectionString = configuration.GetConnectionString("<name>");
        builder.UseMySql(connectionString);
        base.OnConfiguring(builder);
    }
    

    对于 GetService 的强类型版本,不要忘记引用命名空间 Microsoft.Extensions.DependencyInjection。

    【讨论】:

    • 这看起来可行,谢谢。但是我在使用 this.Instance.GetService 时遇到了问题-“'my_accountingContext' 不包含'Instance' 的定义,并且找不到接受'rev_accountingContext' 类型的第一个参数的可访问扩展方法'Instance'(你错过了吗? using 指令或程序集引用?)”。我有 DependencyInjection 的使用和程序集参考。
    • 查看我的编辑。 Instance 属性来自 IInfrastructure.
    • 谢谢。现在,当尝试执行“var configuration = ...”时,它抱怨我在尝试配置它时正在使用某些东西。 '在配置时尝试使用上下文。 DbContext 实例不能在 OnConfiguring 中使用,因为此时它仍在配置中。如果在前一个操作完成之前对此上下文启动了第二个操作,则可能会发生这种情况。不保证任何实例成员都是线程安全的。我做错了什么?谢谢!
    • 您没有做错任何事,但正如您刚刚注意到的那样,我的解决方案存在问题。我认为最好的方法是通过工厂方法将 IConfiguration 的实例传递给 DbContext 派生类,如下面描述的解决方案,然后将其存储并在 OnConfiguring 方法上使用,而不是访问 Instance 属性.
    猜你喜欢
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多