Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interception with Ninject. Fails to load IProxyRequestFactory

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 ?

like image 981
Madushan Avatar asked Aug 23 '12 00:08

Madushan


1 Answers

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.

like image 64
BFree Avatar answered Oct 12 '22 18:10

BFree