Interception with Ninject. Fails to load IProxyRequestFactory
Asked Answered
C

1

5

I'm learning to use Ninject and Interceptor pattern.

I have the following interceptor.

public class MyInterceptor:IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine("Pre Execute: " + invocation.Request.Method.Name);

        foreach (var param in invocation.Request.Arguments)
        {
            Console.WriteLine("param : " + param);
        }

        invocation.Proceed();

        Console.WriteLine("Post Execute: " + invocation.Request.Method.Name);
        Console.WriteLine("Returned: " + invocation.ReturnValue);
    }
}

And have a class named MyClass which got nothing but 2 simple methods, virtual to allow the interceptors to work on them. (Two methods are Echo and double, which does what their name says.)

I added Ninject, Ninject.Extensions.Interception and Ninject.Extensions.Interception.DynamicProxy to my project via NuGet.

Added following using statements.

using Ninject;
using Ninject.Extensions.Interception.Infrastructure.Language;
using Ninject.Extensions.Interception;

My Main method, which does the bootstrapping looks like this.

static void Main(string[] args)
    {
        MyClass o = null;

        using (IKernel kernel = new StandardKernel())
        {

            kernel.Bind<MyClass>().ToSelf().Intercept().With(new MyInterceptor());
            o = kernel.Get<MyClass>();
        }

        o.Echo("Hello World!"); // Error
        o.Double(5);
    }

I'm getting the following error at the specified line.

Error loading Ninject component IProxyRequestFactory
No such component has been registered in the kernel's component container.

Suggestions:
  1) If you have created a custom subclass for KernelBase, ensure that you have  properly
     implemented the AddComponents() method.
  2) Ensure that you have not removed the component from the container via a call to RemoveAll().
  3) Ensure you have not accidentally created more than one kernel..

Can anyone tell me what I'm doing wrong ?

Comp answered 23/8, 2012 at 0:3 Comment(2)
Is the DLL for your Dynamic Proxy in place? Normally, on startup Ninject will .Load files named ninject.extensions.*Supersaturated
Yes, I got Ninject.Extensions.Interception.DynamicProxy from NuGetComp
Y
5

OK, I was finally able to reproduce (forgot to make the MyClass methods virtual). The way I solved it was by removing the using block from around the kernel:

    static void Main(string[] args)
    {
        MyClass o = null;

        var kernel = new StandardKernel();
        kernel.Bind<MyClass>().ToSelf().Intercept().With(new MyInterceptor());
        o = kernel.Get<MyClass>();

        o.Echo("Hello World!"); // Error
        o.Double(5);
        Console.ReadKey(true);
    }

The reason I'm guessing this works is because under the covers it creates a proxy class for MyClass and somehow passes in the IKernel to the proxy. When you invoke the method (on the proxy) it goes back to the kernel and resolves some additional dependencies (including the IProxyRequestFactory). Since you were disposing of it, it was no longer able to resolve that dependency.

Yamada answered 23/8, 2012 at 0:34 Comment(3)
Yes, it works when I put the statements in the using block. Does this means that, once I create the kernel, it needs to be held in memory for the life of my application ? My intention is to use Interception as above, for Logging.Comp
Yes, the kernel should stay in memory for the duration of the application. Ideally, you should never have to new up any objects directly (for the duration of the app) and have them supplied to you by your IoC container.Yamada
Thanks a lot for the answer. The tutorial I was following was absolutely wrong which encourages to keep the Kernel in a using block. Thanks again.Comp

© 2022 - 2024 — McMap. All rights reserved.