2012-07-06 101 views
8

我開始構建一個應用程序,並計劃使用ServiceStack。只是想知道什麼是處理NHibernate ISession或其他「按請求」上下文特定會話對象的最佳實踐/好方法。ServiceStack每個請求的NHibernate會話

我認爲在國際奧委會註冊ISessionFactory,如:

container.Register<ISessionFactory>(sessionFactory); 

並在需要時得到一個新的Session對象,或者......直接提供會話對象:

container.Register<ISession>(c => sessionFactory.OpenSession()).ReusedWithin(ReuseScope.None); 

或者自行處理ISession和通過Global.asax BeginRequest事件的默認事務處理:

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    var session = factory.OpenSession(); 
    ITransaction itrans = session.BeginTransaction(); 
    Context.Items.Add("session", session); 
    Context.Items.Add("trans", itrans); 
} 

所以,我有點迷路,考慮到上述技術或類似的技術,EF或其他Rest-Services框架有哪些最佳實踐?

在此先感謝

回答

3

請參閱此博客張貼的如何最優地使用ServiceStack和NHibernate一起完整的例子:

http://www.philliphaydon.com/2012/06/using-nhibernate-with-servicestack/ 下面是上面的帖子中使用的APPHOST例如:

public class Global : HttpApplication 
{ 
    public class SampleServiceAppHost : AppHostBase 
    { 
     private readonly IContainerAdapter _containerAdapter; 
     public SampleServiceAppHost(ISessionFactory sessionFactory) 
      : base("Service Stack with Fluent NHibernate Sample", typeof(ProductFindService).Assembly) 
     { 
      base.Container.Register<ISessionFactory>(sessionFactory); 
     } 

     public override void Configure(Funq.Container container) 
     { 
      container.Adapter = _containerAdapter; 
     } 
    } 

    void Application_Start(object sender, EventArgs e) 
    { 
     var factory = new SessionFactoryManager().CreateSessionFactory(); 

     (new SampleServiceAppHost(factory)).Init(); 
    } 
} 
4

使用HttpHandler爲每個請求創建一個會話是我找到的最常用的方法。 Ayende解釋說,創建一個會話真的很輕。 http://ayende.com/blog/4123/what-is-the-cost-of-opening-a-session

Ayende實際上有一系列的職位,他逐步建立數據訪問解決方案。每篇文章解釋了他爲什麼做了他所做的事情,以及到目前爲止採取的步驟需要解決哪些問題。從這裏開始:http://ayende.com/blog/4803/refactoring-toward-frictionless-odorless-code-the-baseline

最後,http://nhforge.org/blogs/nhibernate/archive/2011/03/03/effective-nhibernate-session-management-for-web-apps.aspx

以上所有的都是每個請求會話的變化。所有人的共同點是不必手動擔心創建會話/事務。他們將自動提交/回滾事務。

3

我知道這是一個古老的問題,但我想我會繼續,並展示誰仍然對另一個答案感興趣的人,我們如何做到這一點。

我們使用ServiceRunner新ServiceStack API中正是如此:

public class BaseServiceRunner<TRequest> : ServiceRunner<TRequest> 
{ 
    public BaseServiceRunner(AppHost appHost, ActionContext actionContext) 
    : base(appHost, actionContext) { } 

    public override void OnBeforeExecute(IRequestContext requestContext, TRequest request) 
    { 
     var req = request as MyRequestType; 

     if(req == null) 
      base.OnBeforeExecute(requestContext, request); 

     var factory = TryResolve<NHibernate.ISessionFactory>(); 
     var session = factory.OpenSession(); 
     var trans = session.BeginTransaction(IsolationLevel.ReadCommitted); 

     requestContext.SetItem("session", session); 
     requestContext.SetItem("transaction", trans); 
    }   

    public override object OnAfterExecute(IRequestContext requestContext, object response) 
    { 
     var trans = requestContext.GetItem("transaction") as ITransaction; 
     if (trans != null && trans.IsActive) 
      trans.Commit(); 

     var session = requestContext.GetItem("session") as ISession; 
     if (session != null) 
     { 
      session.Flush(); 
      session.Close(); 
     } 

     return base.OnAfterExecute(requestContext, response); 
    } 

    public override object HandleException(IRequestContext requestContext, TRequest request, Exception ex) 
    { 
     var req = request as MyRequestType; 
     if(req != null) 
     { 
      var trans = requestContext.GetItem("transaction") as ITransaction; 
      if (trans != null && trans.IsActive) 
       trans.Rollback(); 

      var session = requestContext.GetItem("session") as ISession; 
      if (session != null) 
      { 
       session.Flush(); 
       session.Close(); 
      } 
     } 
     return base.HandleException(requestContext, request, ex); 
    }   
} 
+1

能否請您闡述一下您是如何使用的呢? ServiceStack文檔對於如何使用這些ServiceRunners確實沒有意義。 – slashp 2013-04-17 05:23:39

+0

我添加了代碼以添加到您的應用程序主機中。不確定如何使用該服務中的Service runner。 – 2013-07-15 10:54:53

+0

剛剛看到有關更多詳細信息的請求,可能已太遲而無法提供幫助,但也許有人想知道。 'code' public class AppHost:AppHostBase { public AppHost():base(「Service」,typeof(AccessService))。大會) {} 公共覆蓋無效配置(集裝箱貨櫃) {} 公共 覆蓋IServiceRunner CreateServiceRunner (ActionContext中ActionContext中) { 返回新BaseServiceRunner (這一點,ActionContext中); '代碼' – 2014-02-07 20:14:44