Ninject - Binding.GetProvider抛出NullReferenceException

Tia*_*ago 8 c# asp.net dependency-injection ninject exception

我在一个asp.net Web表单应用程序中使用Ninject的2.2.0.0版本,在几百个请求之后,它有时会在Binding类的GetProvider方法中抛出NullReferenceException.

堆栈跟踪示例:http://pastebin.com/BbhsPQMT

仅当我对应用程序进行压力测试并且异常的来源通常不同(解析不同的接口)时才会发生异常.

为了试图理解为什么会出现这个问题,我查看了Ninject源代码并插入了一些代码行以用于调试目的.我后来确认null的对象是Binding类中的ProviderCallback属性.

我还在ProviderCallback属性的set运算符中放入了一些代码,以便了解它是否被设置为null.在运行一些测试并查看一些内存转储后,似乎ProviderCallback属性未设置为空值,因此我认为GC正在收集该实例.

我仍然不明白为什么会发生这种情况......

任何帮助是极大的赞赏.

编辑:我们升级到最新版本的Ninject只是为了检查异常是否仍然发生但我们在对应用程序进行压力测试后得到了相同的异常:http://pastebin.com/YaiaZndz

Rem*_*oor 2

我无法告诉您此问题的原因,因为我无法重现这种行为。但您可以采取一些步骤来识别问题。

正如你所说,这个问题是由一个ProviderCallbackthat is引起的null。这不可能是由 GC 引起的,因为 GC 永远不会分配null给属性。相反,您会得到一个已经处理的异常或其他奇怪的行为。但发生这种情况还有其他一些原因:

  1. Null在某个时间分配,但由于您已经验证了这一点,所以这不是原因。
  2. 它根本没有被分配过。
  3. BindingConfiguration稍后会创建一个新的。

通过在构造函数中添加断点可以轻松验证第三点BindingConfiguration。成功配置内核并且开始解析对象后,不应再调用它。

对于第二个问题,在内核配置后执行以下命令:

var kernel = your fully configured kernel;
var bindingsField = typeof(KernelBase).GetField("bindings", BindingFlags.NonPublic | BindingFlags.Instance);
var bindings = bindingsField.GetValue(kernel) as IEnumerable<KeyValuePair<Type, ICollection<IBinding>>>;

foreach (var bindingsEntry in bindings
    .Where(bindingsEntry => bindingsEntry.Value
        .Any(binding => binding.BindingConfiguration.ProviderCallback == null)))
{
    throw new Exception(string.Format("No Provider callback defined for {0}.", bindingsEntry.Key));
}
Run Code Online (Sandbox Code Playgroud)