Ninject: one intercept instance per class instance intercepted?

I am currently having a problem trying to connect exactly one instance of an interceptor to one instance of a class that is intercepted.

I create and advise in InterceptorRegistrationStrategy and set a callback to resolve an interceptor from the kernel (it has an injection constructor). Please note that I can only create an interceptor in the callback because InterceptorRegistrationStrategy does not have a reference to the kernel itself.

            IAdvice advice = this.AdviceFactory.Create(methodInfo);
            advice.Callback = ((context) => context.Kernel.Get<MyInterceptor>());
            this.AdviceRegistry.Register(advice);

I get an interceptor instance for each method.

Is there a way to create one instance of an interceptor for each instance of the instance to be intercepted?

I was thinking about Named Scope, but the intercepted type and the interceptor do not refer to each other.

+2
source share
2 answers

This is not possible because one single interceptor is created for each method for all instances of the binding.

But you can not execute the interception code directly in the interceptor, but rather get an instance of the class that will handle the interception.

public class LazyCountInterceptor : SimpleInterceptor
{
    private readonly IKernel kernel;

    public LazyCountInterceptor(IKernel kernel)
    {
        this.kernel = kernel;
    }

    protected override void BeforeInvoke(IInvocation invocation)
    {
        this.GetIntercpetor(invocation).BeforeInvoke(invocation);
    }

    protected override void AfterInvoke(IInvocation invocation)
    {
        this.GetIntercpetor(invocation).AfterInvoke(invocation);
    }

    private CountInterceptorImplementation GetIntercpetor(IInvocation invocation)
    {
        return this.kernel.Get<CountInterceptorImplementation>(
            new Parameter("interceptionTarget", new WeakReference(invocation.Request.Target), true));                
    }
}

public class CountInterceptorImplementation
{
    public void BeforeInvoke(IInvocation invocation)
    {
    }

    public void AfterInvoke(IInvocation invocation)
    {
    }
}

kernel.Bind<CountInterceptorImplementation>().ToSelf()
      .InScope(ctx => ((WeakReference)ctx.Parameters.Single(p => p.Name == "interceptionTarget").GetValue(ctx, null)).Target);
+5
source

Have you tried to use the free API to configure interception?

Bind<IInterceptor>().To<MyInterceptor>().InSingletonScope();
Bind<IService>().To<Service>().Intercept().With<IInterceptor>();

NB The expansion method Intercept()is inNinject.Extensions.Interception.Infrastructure.Language.ExtensionsForIBindingSyntax

+1
source

All Articles