2

在我的MVC控制器中,我使用了一個IoC容器(Ninject),但我不確定如何在實體框架ObjectContext中最好地使用它。在ASP.NET MVC控制器中管理Entity Framework ObjectContext的依賴注入的正確方法是什麼?

目前,我做這樣的事情:

using(var context = new MyObjectContext()) 
{ 
    var stuff = m_repository.GetStuff(context); 
} 

這是從視圖保持數據庫連接打開最短的時間點來管理的最佳途徑。

如果我要通過Ninject在每個請求的基礎上創建ObjectContext,這顯然會使數據庫連接保持打開狀態的時間過長。

而且上面的代碼將成爲...

var stuff = m_repository.GetStuff(m_myObjectContext); 

(當我將處置方面的...?)

我應該創建的ObjectContext的和合格的工廠通過DI?這會放鬆耦合,但如果沒有簡單的方法維護ObjectContext的接口(我知道),這對真正的可測試性有幫助嗎?

有沒有更好的方法?謝謝

回答

3

這是從保持 數據庫連接在最短時間內打開的角度來管理的最佳方法。

如果我要通過Ninject在每個請求 的基礎上創建ObjectContext,這顯然會使數據庫連接保持打開狀態的時間過長。

實體框架將直接每個查詢(供應來自外部的開放連接時除外)執行後關閉連接,所以你的說法做這樣的事情不成立。

在過去,我曾經通過業務邏輯(我的command handlers準確地說)控制上下文(創建,提交和處置它),但缺點是您需要將此上下文傳遞給所有其他方法和所有依賴關係。當應用程序邏輯變得越來越複雜時,這會導致可讀性差,代碼維護性差。

因爲這個原因,我搬到了一個模型,其中工作單元(您的MyObjectContext)在業務邏輯的控制之外創建,提交併處理。這允許您將工作單元注入到所有依賴項中,併爲所有對象重用相同的工作單元。缺點是這使得你的DI配置有點困難。您需要確保的一些事項:

  1. 必須根據Web請求或在特定範圍內創建工作單元。
  2. 工作單元必須放置在請求或範圍的末尾(儘管DbContext未配置時可能不成問題,因爲下方的連接已關閉,並且DbContext未實施終結器)。
  3. 您需要顯式提交工作單元,但是您無法在Web請求的末尾執行此操作,因爲此時您不知道提交是否安全(因爲您不希望在業務邏輯拋出異常時進行提交,但在請求結束時無法正確檢測這是否真的發生)。

一個提示我可以給你的業務邏輯在周圍command handlers模擬系統,因爲這可以讓你做的定義處理事務行爲的單一裝飾(提交工作單位,甚至在運行一切一個數據庫事務)在一個點上。這個裝飾器可以纏繞在系統中的每個處理器上。

我必須承認,我不知道如何向Ninject註冊泛型類和泛型裝飾器,但在Stackoverflow處詢問時可能會很快得到答案。

相關問題