Ninject InThreadScope绑定

时间:2010-12-23 13:24:56

标签: c# .net asp.net ninject ninject-2

我有一个Windows服务,其中包含一个文件监视器,可在文件到达时引发事件。当一个事件被引发时,我将使用Ninject来创建业务层对象,在它们内部引用了一个Entity Framework上下文,该上下文也是通过Ninject注入的。在我的Web应用程序中,我总是使用InRequestScope作为上下文,在一个请求中,所有业务层对象都使用相同的Entity Framework上下文。在我目前的Windows服务方案中,将实体框架上下文绑定切换到InThreadScope绑定是否足够?

理论上,当服务中的事件处理程序触发它在某个线程下执行时,如果另一个文件同时到达,它将在不同的线程下执行。因此,两个事件都不会共享实体框架上下文,实质上就像网络上的两个不同的http请求一样。

当你看到Ninject wiki时,困扰我的一件事是破坏这些线程范围的对象:

.InThreadScope() - 每个帖子都会创建一个类型的实例 .InRequestScope() - 将为每个Web请求创建一个类型的实例,并在请求结束时销毁。

基于此,我了解InRequestScope对象将在请求结束时(或之后的某个时刻)被销毁(垃圾收集?)。然而,这并没有说明InThreadScope对象是如何被销毁的。回到我的例子,当文件观察器事件处理程序方法完成时,线程消失(回到线程池?)注入的InThreadScope-d对象会发生什么?

修改 现在有一点很清楚,当使用InThreadScope()时,它不会在filewatcher的处理程序退出时销毁你的对象。我能够通过删除文件夹中的许多文件来重现这一点,并最终获得了相同的线程ID,这导致了与之前完全相同的Entity Framework上下文,因此对于我的应用程序来说,这绝对是不够的。在这种情况下,5分钟后出现的文件可能正在使用之前分配给同一线程的陈旧上下文。

1 个答案:

答案 0 :(得分:4)

线程静态的对象可能会存在很长时间,这意味着在某些时候ObjectContext将变得陈旧并使用旧的(缓存的)值,这将导致难以实现发现错误。

我通常创建一个ObjectContext,其范围与创建数据库事务的范围相同(我甚至经常在数据库事务中包装ObjectContext并将它们一个接一个地处理掉)。一个(Web)请求可能有多个数据库事务,但通常会有一个“业务事务”,它执行业务逻辑。其他事务可以作为日志记录启动(在业务事务之前,之后,有时在业务事务期间)。当您为完整请求重用ObjectContext时,最终会出现问题,因为当业务事务失败时,ObjectContext可能处于无效状态,这可能会对操作产生影响(例如记录)重用相同的ObjectContext

使用Windows服务,我认为文件观察程序引发的每个事件都可能触发新的业务事务。在这种情况下,我会为每个事件创建一个新的ObjectContext

长话短说,我不会注入一个由您的IoC框架管理的生命周期ObjectContext。我会注入一个工厂,允许你的代码创建一个新的ObjectContext并处理它。我刚刚回答了另一个问题。看看我在that answer.

中提出的解决方案 祝你好运。