2012-09-29 97 views
4

我遇到了編輯和刪除對象的問題,我認爲它是因爲我沒有在我的存儲庫類和unitofwork類之間共享相同的會話對象。我試圖找到一些文件,以最好的方式來連接這個,所以我共享相同的會話對象。確保您的Repository和UnitOfWork類共享相同的nhibernate會話對象的正確方法是什麼?

我在mvc網站上使用ninject作爲我的IOC容器。

+0

這個問題真的需要更多關注嗎?如果你將'ISession'而不是'ISessionFactory'注入你的工作單元Ninject *將會*在同一個會話中傳遞。 –

回答

5

我通常設置會話作爲倉庫的依賴,因此Ninject可以解決的依賴(的Isession = NHibernate.ISession):

public UserRepository(ISession session) 
{ 
    ... 
} 

這是怎麼了我設置綁定:

kernel.Bind<ISession>().ToMethod(x => GetRequestSession()).InRequestScope(); 

所以當需要一個會話時,Ninject會調用GetRequestSession()來檢索會話。該功能實現如下:

private static ISession GetRequestSession() 
     { 
      IDictionary httpContextItems = HttpContext.Current.Items; 

      ISession session; 
      if (!httpContextItems.Contains(MvcApplication.SESSION_KEY)) 
      { 
       // Create an NHibernate session for this request 
       session = MvcApplication.SessionFactory.OpenSession(); 
       httpContextItems.Add(MvcApplication.SESSION_KEY, session); 
      } 
      else 
      { 
       // Re-use the NHibernate session for this request 
       session = (ISession)httpContextItems[MvcApplication.SESSION_KEY]; 
      } 
      return session; 
     } 

NHibernate會話存儲在HttpContext項目中。這是一個鍵值集合,可用於在處理一個請求期間存儲和共享數據。

會話每個請求只創建一次,並在請求期間重新使用。

MvcApplication.SESSION_KEY只是我在Global.asax中定義的一個常量字符串,它能夠從HttpContext存儲和檢索會話。會話工廠位於global.asax中,並在啓動時創建。

您的工作單元類也可以將ISession設置爲依賴項,因此Ninject也會解析此依賴項,因此會使用同一個會話。另一方面,你可能不需要一個工作單元類,因爲NHibernate本身的ISession實現已經是一個工作單元類。

我不確定這是否是最佳做法,但它對我而言完全適用。

+0

單元課程如何適應這個? – leora

+0

這取決於您的工作單位班級的實施方式。如果它是控制器上的一個屬性,那麼可以讓Ninject將該會話注入到屬性中。 您也可以對工作單元類具有會話依賴性,並讓存儲庫對工作單元類具有依賴性。 Ninject會爲您處理依賴關係鏈。 基本上歸結爲讓Ninject擔心在必要時創建會話。 –

+0

我的unitofwork類代碼在這裏列出:http://stackoverflow.com/questions/12552761/why-would-my-asp-net-mvc-site-using-nhibernate-simply-stop-doing-updates-and-del – leora

1

如果Robin的答案不適合您,您的可能與Ninject存在配置錯誤。

今天早上我遇到了一個非常類似的問題,更新。在我的情況下,我正在讀取綁定到與我正在寫入的會話不同範圍內的對象的會話中的對象。

這裏是我的簡單,SessionProvider:

public class SessionProvider : Provider<ISession> 
{ 
    protected override ISession CreateInstance(IContext context) 
    { 
     var factory = context.Kernel.Get<ISessionFactory>(); 
     var session = factory.OpenSession(); 
     return session; 
    } 
} 

和IOC代碼:

 kernel.Bind<ISessionFactory>().ToProvider<SessionFactoryProvider>(); 
     kernel.Bind<ISession>().ToProvider<SessionProvider>().InRequestScope(); 

,以確保在您的工作單位和你的版本庫的最簡單方法的實例化是相同的Isession是保證它們都是在請求範圍內創建的。但是,這應該是默認設置。

根據您如何安裝NInject和你正在使用,您可能必須安裝一個HTTP模塊,以確保請求範圍的版本可以正常工作:

  1. 如果安裝了NuGet包,它會添加DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
  2. 如果你有Ninject的舊版本,你也可以將模塊添加到使用<add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
  3. 如果您使用的是較新的Ninject web.config中,它在<add name="OnePerRequestHttpModule" type="Ninject.Web.Common.OnePerRequestHttpModule, Ninject.Web.Common"/>
相關問題