为什么NamedScopes从终结器调用dispose方法?

时间:2016-03-19 11:02:55

标签: c# ninject named-scope

我注意到当我在Ninject命名范围内使用IDisposable个对象时,我会从终结器中调用Dispose方法。但是我的目标或其中一些参考文献可能已经​​在那时完成了。

我错过了什么吗?这是正确的行为还是错误?

堆栈跟踪:

в NInjectNamedScopes.User.ChatService.Dispose()
в Ninject.Activation.Strategies.DisposableStrategy.<Deactivate>b__0(IDisposable x)
в Ninject.Activation.InstanceReference.IfInstanceIs[T](Action`1 action)
в Ninject.Activation.Pipeline.<>c__DisplayClass6.<Deactivate>b__4(IActivationStrategy s)
в Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 series, Action`1 action)
в Ninject.Activation.Caching.Cache.Forget(CacheEntry entry)
в Ninject.Activation.Caching.Cache.Forget(IEnumerable`1 cacheEntries)
в Ninject.Activation.Caching.Cache.Clear(Object scope)
в Ninject.Extensions.NamedScope.DisposeNotifyingObject.Dispose(Boolean disposing)
в Ninject.Infrastructure.Disposal.DisposableObject.Finalize()

2 个答案:

答案 0 :(得分:0)

由于ninject仍然引用了您的IDisposable,因此您的IDisposable已经完成的可能性不大。但是在你的情况下,从终结器调用Dispose方法似乎很奇怪。你能提供一个堆栈跟踪吗?

命名范围行为

默认使用InNamedScope,ninject保留WeekReferenceDefinesNamedScope(root),并定期检查它是否仍然有效。一旦检测到它被收集为垃圾,就会处理该范围的InNamedScope - 对象(Ninject会对这些对象保持强烈的引用)。

要确保在范围根对象之后立即放置InNamedScope - d个对象,请将INotifyWhenDisposed添加到范围根目录。

答案 1 :(得分:0)

  1. 一般来说,从终结器访问其他托管对象是一种非常糟糕的做法。
  2. 我在NamedScopes扩展程序的源代码中发现很少与性能相关的其他问题。
  3. 所以是的,这是一个错误,我建议所有人不要使用NamedScopes扩展,直到它被修复。我亲自进行了一些性能测试,并选择了另一个IoC容器AutoFac,它的工作速度提高了一个数量级。