有没有办法工厂注入自定义 DbContext?

Is there a way to factory inject a custom DbContext?

...也许在 EF Core 扩展的 AddDbContextFactory<TContext, TFactory> 中使用 TFactory?

我只见过 AddDbContextFactory being used with just the TContext generic. They're always very explicit to say you have to use a using statement

在类似情况下(当我在 Angular 中使用 Class 或在 .NET Core 中使用 AddScoped 时),我将变量 I want to see in a constructor 作为第一个泛型参数和第二个通用参数实际注入的内容。你知道,比如:

services.AddScoped<IService, RealService>();

显然,

并非如此
services.AddDbContextFactory<ADbContextIHaveBeenInjecting, AFactoryThatWillReturnADbContextIHaveBeenInjecting>();

我希望这会消除整个 using 的需要。

有没有另一种方法可以做到这一点,而不必重新编写每个注入的 DbContext 以符合他们的规定:

public void DoSomething()
{
    using (var context = _contextFactory.CreateDbContext())
    {
        // ...
    }
}

正如我所说,我希望为工厂使用这样的东西:

public class MyDbContextFactory : IDbContextFactory<MyDbContext>
{

    public MyDbContextFactory(DbContextOptions options)
    {
    }

    public MyDbContext CreateDbContext()
    {
        var ProviderName = GetProviderName();
   
        switch (ProviderName)
        {
            case "System.Data.SqlClient":
                return new SqlServerDbContext(new DbContextOptionsBuilder<SqlServerDbContext>().UseSqlServer(ConnectionString).Options);
            case "Npgsql":
                return new PostgreSqlDbContext(new DbContextOptionsBuilder<PostgreSqlDbContext>().UseNpgsql(ConnectionString).Options);
            default:
                throw new NullReferenceException("Missing provider name for DbContext. Should be Npgsql or System.Data.SqlClient");
        }
    }

 
}

然后,在 Startup.cs ConfigureServices 中进行设置,例如:

services.AddDbContextFactory<MyDbContext, MyDbContextFactory>();

所以我可以像这样注入 class:

public class MyController : BaseApiController
{

    private readonly MyDbContext _myDbContext;


    public MyController(MyDbContext myDbContext)
    {
        _myDbContext = myDbContext;
    }


    [HttpGet("GetACount")]
    public IActionResult GetACount()
    {
        var count = _myDbContext.MyRecord.Count();

        return Ok(count);
    }
...

有没有办法使用 AddDbContextFactory 来做到这一点? TFactory 究竟是做什么用的?还有其他方法吗?

依赖注入具体 class。按类型创建工厂 select subclass。使用私有 DbContext _dbContext 创建父级 class。从父class继承子class,并用子class的:base(dbContext)调用父class构造函数。父 class 现在可以在其方法中访问子 class 上下文。子class可以通过设置子class的数据上下文来共享父class的方法(添加,select,更新和删除)。 subclass 将在其构造函数中依赖注入特定的 dbcontext 并在其构造函数中设置父 class dbcontext 变量。然后 subclass 存储库 class 可以访问其主体中的基本 class 方法。

在启动时定义子class 存储库模式

在 public void ConfigureServices(IServiceCollection 服务)

  var connectionString = Configuration.GetConnectionString("ABCContext_DbCoreConnectionString");
  services.AddDbContext<ABCContext>(options1 => options1.UseSqlServer(connectionString));

 services.AddTransient<IRepositoryMySubclass, RepositoryMySubclass>();

sub class

  public RepositorySubclass(ABCContext dbContext) : base(dbContext)
    {
        _dbContext = dbContext;
    }

DbContextFactory 特别 旨在要求您管理 DbContext 的生命周期,因为 Blazor 服务器应用程序不使用像 [=21= 这样的 Scope-per-Http 请求] Core 可以,因此 Scoped DbContext 将不起作用。

如果您想要 Scoped DbContext,只需使用 .AddDbContext 而不是 .AddDbContextFactory

如果您已经注册了 DbContextFactory,但仍想直接在您的服务中注入作用域 DbContext,请按如下方式注册:

    services.AddScoped<MyDbContext>(sp =>
    {
        var cf = sp.GetRequiredService<IDbContextFactory<MyDbContext>>();

        var db = cf.CreateDbContext();

        return db;

    });