【问题标题】:Ninject - In what scope DbContext should get binded when RequestScope is meaningless?Ninject - 当 RequestScope 没有意义时,DbContext 应该在什么范围内绑定?
【发布时间】:2014-04-15 10:59:26
【问题描述】:

在 MVC / WebAPI 环境中,我将使用 InRequestScope 绑定 DbContext。

但是,我现在处于控制台应用程序/Windows 服务/Azure 工作者角色(没关系,只是没有 Web 请求范围),它会定期创建许多异步运行的 Tasks。我希望每个任务都有自己的DbContext,并且由于任务在自己的线程上运行,我尝试使用InThreadScope 绑定DbContext。

不幸的是,我意识到 DbContext 在任务完成时没有被释放。实际发生的是,线程返回到线程池,当它被分配一个新任务时,它已经有一个 DbContext,所以 DbContexts 永远保持活动状态。

有没有办法可以在这里使用InThreadScope,或者我应该使用其他范围?线程时不时地从 ThreadPool 返回时,ThreadScope 怎么用?

【问题讨论】:

  • @Steven 是的,我明白了。那么如何实现自定义范围(或其他解决方案)?
  • 您根本不应该使用范围。使用工厂创建 DbContext(它基本上是一个工作单元) - 并根据需要传递它。如果软件像您描述的那样简单,您还可以使用命名范围(由任务定义并绑定 DbContext InNamedScope)。但这不是未来的证明,例如,当您想在任务之外创建 DbContext 或者当您想在单个任务中拥有多个(顺序)DbContext 时,......等等
  • @Steven 我同意 100%。只是为了向其他读者澄清一下:Ninject 具有“范围”的概念。绑定“在”范围内告诉 ninject 何时创建一个实例以及何时重用一个实例。我们没有使用那种范围。我也不会完全说我们将它与请求结合起来。我们收到了 WCF 请求,并且收到了来自硬件设备的事件。一些 WCF 请求或事件可能会指示我们做几件事,这可能需要几个工作单元,有时甚至是异步的或在稍后的时间点(如计划或其他)。有时需要工作单元的操作可能是嵌套的。
  • @WahidBitar 是:1) 使用工厂创建 UnitOfWork,将其传递并在最后处理,2) 使用工厂创建 UnitOfWork,并使用类似 @987654322 的东西@ 无需传递即可访问它。

标签: multithreading entity-framework dependency-injection ninject threadpool


【解决方案1】:

如果您决定继续使用自定义范围,解决方案是:

public sealed class CurrentScope : INotifyWhenDisposed
{
    [ThreadStatic]
    private static CurrentScope currentScope;

    private CurrentScope()
    {
    }

    public static CurrentScope Instance => currentScope ?? (currentScope = new CurrentScope());

    public bool IsDisposed { get; private set; }

    public event EventHandler Disposed;

    public void Dispose()
    {
        this.IsDisposed = true;
        currentScope = null;
        if (this.Disposed != null)
        {
            this.Disposed(this, EventArgs.Empty);
        }
    }
}

绑定:

Bind<DbContext>().To<MyDbContext>().InScope(c => CurrentScope.Instance)

最后:

using (CurrentScope.Instance)
{
    // your request...
    // you'll get always the same DbContext inside of this using block
    // DbContext will be disposed after going out of scope of this using block
}

【讨论】:

  • 您是否必须在 using 块中解决您的依赖关系才能使其工作?
  • @IronSean,是的 using 块定义了你的依赖的生命周期。
猜你喜欢
  • 1970-01-01
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
  • 2019-01-25
  • 1970-01-01
  • 1970-01-01
  • 2016-07-19
  • 1970-01-01
相关资源
最近更新 更多