如何利用ASP.NET Core LifeCycle中的DbContext池?

时间:2019-03-30 19:31:06

标签: c# asp.net-core entity-framework-core

每组用户有一个对象,用于管理内存中的并发更改。以固定的速度,例如每六秒钟,我获取更改的当前状态并将其应用到数据库。重要的是,有一个单独的线程需要一个ASP.NET Core MVC LifeCycle之外的dbcontext实例。这很困难,或者我不知道如何利用in亵注射。

在此问题空间中是否有办法利用AddDbContextPool。似乎没有办法直接租用AppDbContext,并且Microsoft警告不要直接创建AppDbContext,因为其API可能会发生变化。据我所知,我没有办法将数据库上下文注入/租用正在执行工作的线程。

我正在使用Reactive API处理线程,在其中创建一个Subjects并使用Sample管道,如下例所示:

UpdateSubject
    .Sample(TimeSpan.FromSeconds(6))
    .Subscribe(x => {

        // This is where I'd like to take 
        // advantage of the dbcontext pooling
        using(AppDbContext db = new AppDbContext){

            // ...
            // Iterate Over Changes
            // ...

            db.SaveChanges();
        }

   });

我当前的感知选项是。

  1. 不执行任何操作:该体系结构已经在整合呼叫。
  2. 实现我自己的资源池,并研究如何为自己的每次使用重置上下文,
  3. 使用/实现Microsoft内部类DbContextPool我自己,尽管有警告它严格供内部使用,并且API可能会更改
  4. 在不改变其功能方式的情况下,找到一种使它脱离ASP.NET Core MVC生命周期的方法,即在我的用例中找到一种利用依赖注入的方法。
  5. *接受建议

1 个答案:

答案 0 :(得分:1)

提出问题可以帮助我回答自己的问题或找到解决方案。下面的所有内容均使用在请求外部运行的线程进行了测试。

结果证明,我们可以通过API注入服务提供者以创建自己的实例!

ReadOnly IServiceProvider _ServiceProvider;

MySingulation(IServiceProvider serviceProvider)
{
    _ServiceProvider = serviceProvider;
}

一旦通过注入获得了IServiceProvider的句柄,就可以使用MVC Core API创建上下文实例

using(var serviceScope = _ServiceProvider.CreateScope())
{
    // Don't get confused -- Call GetService from the serviceScope and 
    // not directly from the member variable _ServiceProvider. 
    var context = serviceScope.ServiceProvider.GetService<YourAppDbContext>();

    // ...
    // Make use of the dbcontext
    // ...

}

现在,重要的是要记住我们首先要使用Startup.cs中的MVC核心池。

public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddDbContextPool<YourAppDbContext>(options => {
        options.UseSqlServer(settings.Connection);
    });

    // Oh, it's important the singultion was created within Core's LifeCycle/API
    services.AddSingleton<MySingulation>();
    //...
}