2016-08-03 10 views
0

Я использую ninject для управления сеансом для приложения Web API/MVC. Код выглядит следующим образом:Ninject 3.2 OnDeactivation не запускает веб-API

Bind<ISession>().ToMethod(c => c.Kernel.Get<ISessionFactory>().OpenSession()) 
      .InRequestScope() 
      .OnActivation(s => s.BeginTransaction()) 
      .OnDeactivation((s) => 
      { 
       try 
       { 
        s.Transaction.Commit(); 
       } 
       catch (Exception e) 
       { 
        s.Transaction.Rollback(); 
       } 

       s.Close(); 
       s.Dispose(); 
      }); 
    } 

код OnActivation называется правильно - когда сеанс вводится транзакция началась. Однако, когда запрос заканчивается, ondeactivation не вызывается. Поэтому я могу запрашивать вещи из базы данных, но не фиксировать изменения (если я не совершаю транзакцию в другом месте).

Я не совсем уверен, почему OnDeactivation не вызывается - я что-то упустил в своей настройке ninject?

ответ

0

Вызов Commit во время OnDeactivation действительно плохая идея, потому что OnDeactivation будет всегда можно назвать, даже если исключение внутри бизнес-слоя. В случае ошибки вы явно не хотите совершать транзакцию.

Вы должны рассмотреть возможность совершения на другом уровне. This q/a рассказывает об этом более подробно и показывает, как решить эту проблему.

Также обратите внимание, что ваш код является чрезмерно подробным. Если вы звоните Dispose, вам не нужно звонить Close, и если вы вызываете Dispose по незафиксированной транзакции, транзакция автоматически откатывается. Вы даже можете вытащить вилку, база данных автоматически откатится от незафиксированной транзакции. Другими словами, вы можете легко упростить код на следующее:

.OnDeactivation((s) => 
{ 
    try 
    { 
     s.Transaction.Commit(); 
    } 
    finally 
    { 
     s.Dispose(); 
    } 
}); 

Вы можете даже удалить Dispose когда вы делаете использование OnePerRequestHttpModule, как это описано here. Это уменьшает код дальше:

.OnDeactivation(s => s.Transaction.Commit()); 

Но опять же, OnDeactivation абсолютно неправильное место, чтобы совершить.

+0

отметил - будет перемещать фиксацию в другом месте. моя проблема заключалась в том, что ondeactivation не вызывается (когда-либо), хотя - любая идея, почему это может быть? – Bonnotbh

+1

@Bonnotbh OnDeactivation и утилизация обычно недетерминирована в Ninject. Ninject очистится после сбора мусора на GC. Это часто не работает для соединений с базой данных. – Steven