【问题标题】:How should NHibernate session be handled in Nancy for session-per-request?NHibernate 会话应该如何在 Nancy 中处理每个请求的会话?
【发布时间】:2012-06-30 11:22:30
【问题描述】:

真的,我的问题在标题中...... NHibernate 会话应该如何在 Nancy 中处理,以便每个请求的会话?如果您对此本身有一个很好的答案,那就去做吧……如果您需要更多背景知识,那就是:


我习惯于在 ASP.NET MVC 中使用 actionFilter 在 Web 请求的开始和结束时打开和关闭 NHibernate 上下文中的会话。这样,请求上下文中的每个数据库操作都使用相同的会话。

我以为我在使用 Nancy 的新项目中设置了相同的东西,但每次需要会话时,都会生成一个新会话。以下是我在引导程序中处理会话打开和关闭的方式(继承自 StructureMapBootstrapper):

protected override void RequestStartup(IContainer container, IPipelines pipelines, NancyContext context)
{
    var sessionContainer = container.GetInstance<ISessionContainer>();
    pipelines.BeforeRequest.AddItemToStartOfPipeline(x =>
    {
        sessionContainer.OpenSession();
        return x.Response;
    });
    pipelines.AfterRequest.AddItemToEndOfPipeline(x => sessionContainer.CloseSession());
}

我的ISessionContainer 基于类似于this site 的东西。我对ISessionContainer 的实现使用NHibernate 的会话上下文来获取“当前会话”。

现在,当我在我的 Nancy 项目中尝试此操作时,每次请求 ISessionContainer.Session 属性时都会返回一个新会话。我认为这是因为 Nancy 默认情况下未启用基于 cookie 的会话,所以我将其添加到我的引导程序中:

protected override void ApplicationStartup(IContainer container, IPipelines pipelines)
{
    CookieBasedSessions.Enable(pipelines);
}

没有骰子。每次请求时,我仍然会得到一个新会话。

但是,真的,我不想诊断我的问题。我宁愿听听在 Nancy 中处理 NHibernate 会话管理的标准方法是什么。

【问题讨论】:

    标签: c# nhibernate session-management nancy


    【解决方案1】:

    DinnerParty 是 Nancy 和 RavenDB 的 NerdDinner 的一个端口,最近由 Ayende 在这里http://ayende.com/blog/156609/reviewing-dinner-party-ndash-nerd-dinner-ported-to-ravendb-on-ravenhq?key=0c283ada-e5e8-4b7c-b76b-e9d27bfc0bf9

    进行了审核

    我相信它使用按请求会话,因为我记得指出如何使用自定义模块构建器。看看引导程序和 RavenAwareModuleBuilder

    【讨论】:

    • 我现在正在关注 DinnerParty。一下子看不出来。你还记得它在哪里管理会话吗?
    【解决方案2】:

    在我的Nancy port of the RestBucks sample 中,我以每个请求的方式使用 NHibernate。

    bootstrapper from that sample 我有以下NHibernate 设置:

    protected override void ApplicationStartup(IWindsorContainer container, 
                                               Nancy.Bootstrapper.IPipelines pipelines)
    {
      base.ApplicationStartup(container, pipelines);
      pipelines.BeforeRequest += ctx => CreateSession(container);
      pipelines.AfterRequest += ctx => CommitSession(container);
      pipelines.OnError += (ctx, ex) => RollbackSession(container);
      // Other startup stuff 
    }
    
    private Response CreateSession(IWindsorContainer container)
    {
      var sessionFactory = container.Resolve<ISessionFactory>();
      var requestSession = sessionFactory.OpenSession();
      CurrentSessionContext.Bind(requestSession);
      requestSession.BeginTransaction();
    
      return null;
    }
    
    private AfterPipeline CommitSession(IWindsorContainer container)
    {
      var sessionFactory = container.Resolve<ISessionFactory>();
      if (CurrentSessionContext.HasBind(sessionFactory))
      {
        var requestSession = sessionFactory.GetCurrentSession();
        requestSession.Transaction.Commit();
        CurrentSessionContext.Unbind(sessionFactory);
        requestSession.Dispose();
      }
      return null;
     }    
    
    private Response RollbackSession(IWindsorContainer container)
    {
      var sessionFactory = container.Resolve<ISessionFactory>();
      if (CurrentSessionContext.HasBind(sessionFactory))
      {
        var requestSession = sessionFactory.GetCurrentSession();
        requestSession.Transaction.Rollback();
        CurrentSessionContext.Unbind(sessionFactory);
        requestSession.Dispose();
      }
      return null;
    }
    

    您希望如何设置 NHibernate 会话可能会有所不同。

    【讨论】:

    • 你使用“CurrentSessionContext”的什么实现?使用 ThreadStaticSessionContext 它可能看起来可以工作,但这是一个非常脆弱的实现,如果您使用异步/任务,它将在重负载下中断。据我了解,在自托管的 Nancy 应用程序中,理论上没有任何实现可以处理异步请求。
    猜你喜欢
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 2017-06-17
    • 1970-01-01
    相关资源
    最近更新 更多