Ninject InThreadScope绑定

e36*_*6M3 6 .net c# asp.net ninject ninject-2

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

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

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

.InThreadScope() - 每个线程将创建一个类型的实例.
.InRequestScope() - 将根据Web请求创建一个类型的实例,并在请求结束时销毁.

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

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

Ste*_*ven 4

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

我通常会创建一个ObjectContext与创建数据库事务具有相同作用域的 an (我什至经常将 a 包装ObjectContext在数据库事务中,然后将它们依次处理)。一个(Web)请求可能有多个数据库事务,但通常只有一个执行业务逻辑的“业务事务”。可以启动其他事务作为日志记录(在业务事务之前、之后,有时在业务事务期间)。当您为完整的请求重用 时ObjectContext,您可能会陷入混乱,因为当业务事务失败时,ObjectContext可能处于无效状态,这可能会影响重用该相同 的操作(例如日志记录)ObjectContext

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

长话短说,我不会注入一个ObjectContext由 IoC 框架管理的生命周期。我会注入一个工厂,允许您的代码创建一个新工厂ObjectContext并对其进行处理。我刚刚回答了我们几个人的另一个问题。看看我在该答案中提出的解决方案。

祝你好运。