【问题标题】:Ninject, DbContext & Windows Service - New Instance Each Time Thread Runs?Ninject、DbContext 和 Windows 服务 - 每次线程运行时都有新实例?
【发布时间】:2013-09-06 10:44:30
【问题描述】:

我目前正在编写一个 Windows 服务,它使用实体框架 (DbContext) 连接到现有服务层,并使用 Ninject 注入 Respositories 和 DbContext 实例。这几乎与一个警告一起工作 - 每次线程运行时我都想要一个全新的 DbContext 实例,而目前我在整个线程生命周期中都得到相同的实例。

我的绑定看起来像这样:

Bind<IDbContext>().To<EnterpriseDbContext>().InThreadScope();
Bind<IUserRepository>().To<UserRepository>().InThreadScope();
// And other repositories

我的线程代码如下所示:

[Inject]
public IDbContext DbContext { get; set; }

// Execute indefinitely (or until we've stopped)
while (true && !isStopping)
{
   try
   {
      // Do work.

      // Save any changes.
      DbContext.SaveAnyChanges();
    } 
    catch (Exception ex)
    {
       // Handle exception
       HandleException(ex);
    }

    // Sleep
    Thread.Sleep(sleepInterval);
 }

现在我知道我可以将范围更改为 InTransientScope() 等 - 但是我对 Ninject 还是很陌生,我不确定如何最好地组织代码以每次都使用新的 DbContext 实例。

有没有人做过类似的事情?在 Web 应用程序中,我们有 InRequestScope() 可以完美运行 - 但我不确定如何在 Windows 服务中使用 DbContext 的最佳方法。

【问题讨论】:

    标签: .net entity-framework windows-services ninject dbcontext


    【解决方案1】:

    See here for the answer

    在 Ninject2 中,您可以这样做:

    Bind<IService>().To<ServiceImpl>().InScope(ctx => ...);
    

    传递给InScope() 的回调返回的对象成为范围内激活的实例的“拥有”对象。这有两个意思:

    1. 如果回调为多次激活返回同一个对象,Ninject 将重新使用第一次激活的实例。

    2. 当回调返回的对象被垃圾回收时,Ninject 将停用(“拆除”、调用 Dispose() 等)与该对象关联的任何实例。

    例如InRequestScope()使用的回调是:

    ctx => HttpContext.Current
    

    由于 HttpContext.Current 在每个 Web 请求上都设置为 HttpContext 的新实例,因此每个请求只会激活一个服务实例,并且当请求结束并且 HttpContext 是(最终)收集,实例将被停用。

    如果您想确定性地停用“拥有”实例,回调返回的对象还可以实现INotifyWhenDisposed,这是 Ninject 的一个接口。如果作用域对象实现了这个接口,当它被 Dispose()'d 时,它所拥有的任何实例都将被立即停用。

    【讨论】:

    • 谢谢@qujck - 这为我指明了正确的方向:)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多