Ninject Interception - CreateInterceptor вызывается несколько раз - PullRequest
0 голосов
/ 05 марта 2012

Я использую Ninject Interception Extension и настроил класс атрибута следующим образом:

public class TransactionAttribute : InterceptAttribute
{
    public override IInterceptor CreateInterceptor(IProxyRequest request)
    {
        Debug.WriteLine("##################### CreateInterceptor  ####################### " + request.Target.GetHashCode() + " " + request.Target.GetType().Name);
        return new TransactionInterceptor();
    }
}

И перехватчик выглядит следующим образом:

public class TransactionInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        var service = invocation.Request.Target as ServiceBase;

        try
        {
            Debug.WriteLine("##################### BEGIN  ####################### " + service.GetHashCode());
            service.TransactionManager.Begin();

            invocation.Proceed();

            Debug.WriteLine("##################### COMMIT ####################### " + service.GetHashCode());
            service.TransactionManager.Commit();
        }
        catch (Exception ex)
        {
            Debug.WriteLine("#################### ROLLBACK ###################### " + service.GetHashCode());
            service.TransactionManager.Rollback();

            throw;
        }
    }
}

В своих привязках я связал несколько классов следующим образом:

this.Bind<TicketHandler>().ToSelf().OnActivation(c => Debug.WriteLine("##################### Activating TicketHandler"));

Ожидаемый результат отладки этого шаблона должен быть следующим:

##################### Activating CloseActivityHandler
##################### CreateInterceptor ####################### 28138265 CloseActivityHandler
##################### BEGIN  ####################### 28138265
##################### POST  ####################### 28138265
##################### COMMIT ####################### 28138265

Это именно то, что я вижу для первых нескольких вызовов во время сеанса отладки. Но затем я начинаю видеть, что CreateInterceptor вызывается более одного раза, что приводит к нескольким вызовам перехватчика для каждого отдельного вызова исходного перехваченного метода. Например:

##################### Activating CloseActivityHandler
##################### CreateInterceptor ####################### 28138265 CloseActivityHandler
##################### CreateInterceptor ####################### 28138265 CloseActivityHandler
##################### BEGIN  ####################### 28138265
##################### BEGIN  ####################### 28138265
##################### POST  ####################### 28138265
##################### COMMIT ####################### 28138265
<Exception thrown by second commit>

Как только этот шаблон запускается, он постепенно ухудшается, увеличивая количество раз, которое CreateInterceptor вызывается по одному каждый раз. Посредством отладки - я вижу, что в каждом случае invocation.Request.Target указывает на один и тот же экземпляр объекта, а не на обертку - кажется, что несколько перехватчиков связаны с одним и тем же объектом.

Если я отлавливаю любые вызовы CreateInterceptor в отладчике, трассировка стека начинается с DynamicProxyWrapper.Intercept во всех случаях. До этого стек указывает на внешний код.

Я запускаю свое веб-приложение на сервере разработки ASP.NET (Кассини). Ninject 2.2.0.0. Я также попробовал реализацию LinFu, но вижу ту же проблему.

...