Я использую 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, но вижу ту же проблему.