Pergunta

No momento, estou tendo um problema, tentando conectar exatamente uma instância do interceptor por uma instância da classe sendo interceptada.

Estou criando um Conselho no InterceptorRegistrationStrategy e configurando o callback para resolver um interceptor do kernel (ele tem um construtor de injeção).Observe que só posso instanciar o interceptor no retorno de chamada porque InterceptorRegistrationStrategy não tem referência ao próprio Kernel.

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

Estou recebendo uma instância de interceptor por método.

Existe alguma maneira de criar uma instância de interceptador por tipo de instância que está sendo interceptada?

Eu estava pensando em Named Scope, mas o tipo interceptado e o interceptor não fazem referência um ao outro.

Foi útil?

Solução

Isso não é possível, pois um único interceptor é criado por método para todas as instâncias de uma ligação.

Mas o que você pode fazer não é executar o código de interceptação diretamente no interceptor, mas obter uma instância de uma classe que tratará da interceptação.

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);

Outras dicas

Você já tentou usar a API fluente para configurar sua interceptação?

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

N.B.O método de extensão Intercept() está em Ninject.Extensions.Interception.Infrastructure.Language.ExtensionsForIBindingSyntax

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top