2016-08-03 16 views
0

我正在使用ninject來管理Web API/MVC應用程序的會話。代碼如下:Ninject 3.2 OnDeactivation沒有發射Web 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

調用期間OnDeactivationCommit是一個非常糟糕的主意,因爲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在Ninject中,去激活和處置通常是不確定的。由GC收集垃圾後,Ninject將清理。這對於數據庫連接通常是不可行的。 – Steven