Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ninject - Binding.GetProvider throws NullReferenceException

I'm using version 2.2.0.0 of Ninject in a asp.net web forms application and after a few hundred requests, it sometimes throws a NullReferenceException in the GetProvider method of the Binding class.

Example stack trace: http://pastebin.com/BbhsPQMT

The exception only occurs when I stress test the application and the origin of the exception is usually different (resolving distinct interfaces).

In order to try to understand why this issue was ocurring I looked at the Ninject source code and inserted some lines of code for debugging purposes. I later confirmed that the object that is null is the ProviderCallback property in the Binding class.

I also put some code in the set operator of the ProviderCallback property in order to understand if it was being set to null. After running some tests and looking at some memory dumps it seems that the ProviderCallback property is not being set to a null value and so I think the instance being collected by GC.

I still do not understand why this is happening...

Any help is greatly appreciated.

Edit: We upgraded to the latest version of Ninject just to check if the exception still occurs but we got the same exception after stress testing the application: http://pastebin.com/YaiaZndz

like image 957
Tiago Avatar asked Nov 20 '12 14:11

Tiago


1 Answers

I can't tell you the reason for this issue as I can't reproduce such a behavior. But here are some steps you can take to identify the problem.

As you say the issue is caused by a ProviderCallback that is null. This can't be caused by GC because GC will never assign null to a property. Instead you will get an already disposed exception or other strange behaviors. But there are some other reasons how this can happen:

  1. Null is assigned at some time, but since you verified this already this is not the reason.
  2. It was never assigned at all.
  3. A new BindingConfiguration is created at a later time.

The 3rd point can easily be verified by adding a breakpoint in the BindingConfiguration constructor. It shouldn't be called anymore after the kernel is succesfully configured and you start resolving objects.

For the second problem execute the following after the kernel configuration:

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));
}
like image 162
Remo Gloor Avatar answered Sep 22 '22 09:09

Remo Gloor