0

I upgraded Ninject from 2.2 to 3.2. Before, the interception worked fine, but now if I set a breakpoint I can see that the parameterless constructor is getting called after the constructor that has the parameters that Ninject is injecting. It wasn't getting hit before. The result of this is that my private variable is now null.

Here's what my code looks like:

public class ContentHandler : IContentHandler
{
    IClientGateway _clientGateway;

    protected ContentHandler()
    {
        // This is hit after the other constructer when using Ninject 3.2 but not 2.2.
        // I think this is what is causing _clientGateway to be null.
    }

    public ContentHandler(IClientGateway clientGateway)
    {
        // This gets hit first regardless of Ninject version.
        this._clientGateway = clientGateway;
    }

    public IClientContent GetClientContent(int clientID)
    {
        // _clientGateway is null and throws an exception here :(
        IClient client = this._clientGateway.GetClientbyClientID(clientID);
    }

What am I doing wrong? In my global.asax, I have this:

kernel.Intercept(ctx => ctx.Request.Service == typeof(IClientGateway))
      .With(InterceptorFactory.GetInterceptor());

The InterceptorFactory looks like this:

public static class InterceptorFactory
{
    private static IKernel _kernel = new StandardKernel(new LoggingInterceptionModule());

    public static ExceptionInterceptor GetInterceptor()
    {
        return GetExceptionInterceptor();
    }

    private static ExceptionInterceptor GetExceptionInterceptor()
    {
        return _kernel.Get<ExceptionInterceptor>();
    }
}

The ExceptionInterceptor looks like this:

public class ExceptionInterceptor : IInterceptor
{
    private LoggingConnector _loggingConnector;
    private const string _logFormat = "Exception occured during invoke of {0} in {1} with arguments {2} EXCEPTION: {3}";

    public ExceptionInterceptor(LoggingConnector lc)
    {
        _loggingConnector = lc;
        _loggingConnector.SetLevel(LogLevel.Error);
    }

    public void Intercept(IInvocation invocation)
    {
        try
        {
            invocation.Proceed();
        }
        catch (Exception e)
        {
            _loggingConnector.Write(String.Format(_logFormat, invocation.Request.Method, invocation.Request.Target, invocation.Request.Arguments, e.StackTrace));

            throw e;
        }
    }
}

Thanks for your help.

adam0101
  • 29,096
  • 21
  • 96
  • 174
  • 2
    Possible duplicate of [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Fᴀʀʜᴀɴ Aɴᴀᴍ Dec 08 '15 at 16:29
  • 1
    @Farhan, yeah, not even close to a duplicate of that. I already know why I'm getting the null reference exception. The question is why the private variable is null. Please read the question. – adam0101 Dec 08 '15 at 16:30
  • 1
    Yes, why not. After you edit the title it will change, won't it? – Fᴀʀʜᴀɴ Aɴᴀᴍ Dec 08 '15 at 16:38
  • I don't think the ctor of the same object can be called twice. Are you sure both ctors are being called and not only the one without parameters? If both are called, can you provide a callstack for both? Or an [MCVE](http://stackoverflow.com/help/mcve) otherwise? – BatteryBackupUnit Dec 08 '15 at 16:54
  • @Farhan, just because I was getting a null reference exception as a symptom doesn't mean that I don't know what a null reference exception is. The question has always been why there is a different behavior between Ninject versions. – adam0101 Dec 08 '15 at 16:56
  • @BatteryBackupUnit, yes both constructors are being called, but probably not on the same instance if that's what you're thinking. The proxy is probably creating a new instance and calling the parameterless constructor. The callstack only has the one entry in it. – adam0101 Dec 08 '15 at 17:01
  • @adam0101 i believe it's related to this: http://stackoverflow.com/a/22350178/684096 – BatteryBackupUnit Dec 08 '15 at 17:01
  • @BatteryBackupUnit, the solution at the bottom of your answer on that page sounds like what I'm already doing (with the protected parameterless constructor). I'm not sure what I need to change. – adam0101 Dec 08 '15 at 17:28
  • Then please post an [MCVE](http://stackoverflow.com/help/mcve) so I (and others..) can have a look at it. – BatteryBackupUnit Dec 09 '15 at 09:38
  • @BatteryBackupUnit, using your example on that page I was able to get the interceptor working by injecting the concrete class into my controller instead of the interface, but I don't understand why I can't use the interface. Isn't the whole point of using Ninject to decouple the concrete implementations? – adam0101 Dec 10 '15 at 14:44
  • @adam0101 of course it is preferrable to inject the interface instead of the class. I've experienced unsupported use cases with `Ninject.Extensions.Interception` before that's why i usually roll my own thing rather than using `Ninject.Extensions.Interception`. Using castle.DynamicProxy directly for a [interface proxy with target](http://kozmic.net/2009/04/01/castle-dynamic-proxy-tutorial-part-ix-interface-proxy-with-target/) is actually not that difficult. – BatteryBackupUnit Dec 10 '15 at 16:59
  • I have exactly the same problem. Have you been able to resolve or reproduce it? I have found similar problem in this discussion https://groups.google.com/forum/#!topic/ninject/O0RRk1JpQ-I – Yevgeniy.Chernobrivets Oct 18 '16 at 08:15

0 Answers0