Ninject: один экземпляр-перехватчик на один экземпляр класса, который перехватывается? - PullRequest
2 голосов
/ 18 марта 2011

У меня сейчас проблема: я пытаюсь подключить ровно один экземпляр перехватчика на один экземпляр перехватываемого класса.

Я создаю Advice в InterceptorRegistrationStrategy и устанавливаю обратный вызов для разрешения перехватчика из ядра (в нем есть конструктор инъекций). Обратите внимание, что я могу только создать экземпляр перехватчика в обратном вызове, потому что InterceptorRegistrationStrategy не имеет ссылки на само ядро.

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

Я получаю экземпляр перехватчика для каждого метода.

Есть ли способ создать один экземпляр перехватчика для каждого перехваченного экземпляра типа?

Я думал о Named Scope, но перехваченный тип и перехватчик не ссылаются друг на друга.

Ответы [ 2 ]

5 голосов
/ 19 марта 2011

Это невозможно, поскольку для каждого экземпляра привязки создается один отдельный перехватчик.

Но вы можете не выполнять код перехвата непосредственно в перехватчике, а получить экземпляр класса, который будет обрабатывать перехват.

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);
1 голос
/ 18 марта 2011

Вы пытались использовать свободный API для настройки перехвата?

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

Примечание: метод расширения Intercept() находится в Ninject.Extensions.Interception.Infrastructure.Language.ExtensionsForIBindingSyntax

...