0

基於我在Entity Framework in layered architecture處給出的問題給出的答案,現在我想將我的存儲庫(現在只負責CRUD抽象,而不是業務邏輯的東西)移動到DAL並保留業務邏輯的BLL。
我得出的結論是,實體環境應該被視爲一個工作單元,因此不會被重用。所以我想在我的倉庫中爲每個HttpContext創建一個obejctcontext來防止性能/線程[un]安全問題。我想在庫定義的ObjectContext如下:訪問數據訪問層中的HttpContext.Current

public MyDBEntities ctx 
    { 
     get 
     { 
      string ocKey = "ctx_" + HttpContext.Current.GetHashCode().ToString("x"); 
      if (!HttpContext.Current.Items.Contains(ocKey)) 
       HttpContext.Current.Items.Add(ocKey, new MyDBEntities()); 
      return HttpContext.Current.Items[ocKey] as MyDBEntities ; 
     } 
    } 

在這種情況下,DAL項目應該知道HttpContext.Current變量。我不確定這是否是一種好的做法,並希望知道您的意見。

+0

來吧夥計,任何人? – Kamyar 2011-01-06 07:51:38

回答

2

在Web應用程序之外不訪問HttpContext是不好的做法,因爲它將代碼緊密地耦合到Web環境。你正在尋找的可能是每個HTTP請求對象生存期管理器的控制容器的反轉。

假設爲你定義你的業務邏輯:

public class BusinessService : IBusinessService 
{ 
    // Constructor with dependency injection 
    public BusinessService(IObjectContext context) 
    { ... } 

    ... 
} 

現在,當你想使用的BusinessService你必須創建它的實例,並將其傳遞IObjectContext的作爲參數。當使用控制容器的反轉,你可以利用這個定義的優勢,而不是構造函數的調用是這樣的:

IBusinessService service = container.Resolve<IBusinessService>(); 

反轉控制(IOC)容器必須被配置爲能夠實例化具體實施IBusinessService和IObjectContext的的。而且這個配置通常允許定義實例化對象的生命週期。當允許每個HTTP生命週期時,在單個請求中解析的每個調用返回相同的實例。

通過讓容器使用業務服務解析類,您甚至可以走得更遠。通常通過ASP.NET MVC完成。在這種情況下,您只需將接收服務的構造函數定義爲主類(控制器)中的參數,並讓IoC容器構建整個對象層次結構。

反轉控制容器檢查例如Windsor Castle。我正在使用MS Unity,但它不提供每個HTTP生命週期管理器。

+0

+1好答案。我使用StructureMap來管理每個Http請求的OC。它具有開箱即用的HTTP生命週期管理。 – RPM1984 2011-01-06 10:01:08