Как следует обрабатывать сеанс NHibernate в Нэнси для сеанса на запрос?

Действительно, мой вопрос в заголовке... Как следует обрабатывать сеанс NHibernate в Нэнси для сеанса на запрос? Если у вас есть хороший ответ на этот вопрос сам по себе, дерзайте... если вам нужно больше информации, вот она:


Я привык использовать actionFilter в ASP.NET MVC для открытия и закрытия сеанса в контексте NHibernate в начале и конце веб-запроса. Таким образом, каждая операция базы данных в контексте запроса использует один и тот же сеанс.

Я думал, что в моем новом проекте, использующем Нэнси, настроено то же самое, но каждый раз, когда требуется сеанс, создается новый. Вот как я обрабатываю открытие и закрытие сеанса в моем загрузчике (наследующем от 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 основан на чем-то похожем на этот сайт. Моя реализация ISessionContainer использует контекст сеанса NHibernate для получения «текущего сеанса».

Прямо сейчас, когда я пробую это в своем проекте Нэнси, каждый раз, когда запрашивается свойство ISessionContainer.Session, возвращается новый сеанс. Я подумал, что это связано с тем, что сеансы на основе файлов cookie по умолчанию не включены в Nancy, поэтому я добавил это в свой загрузчик:

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

Нет игральных костей. Мне по-прежнему дают новую сессию каждый раз, когда я ее прошу.

Но, на самом деле, я не хочу диагностировать свою проблему. Я бы предпочел услышать, каков стандартный способ управления сеансом NHibernate в Нэнси.


person Byron Sommardahl    schedule 28.06.2012    source источник


Ответы (2)


В моем порте Nancy образца RestBucks я использую NHibernate в режиме сеанса для каждого запроса.

В загрузчике из этого примера у меня есть следующая настройка 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, скорее всего, будет отличаться.

person Christian Horsdal    schedule 29.06.2012
comment
Какую реализацию CurrentSessionContext вы используете? С ThreadStaticSessionContext может показаться, что он работает, но это очень хрупкая реализация и сломается при большой нагрузке, если вы используете async/Tasks. Насколько я понимаю, нет реализации, которая могла бы даже теоретически обрабатывать асинхронные запросы в собственном приложении Nancy. - person Alex Uslontsev; 13.07.2016

DinnerParty — это порт NerdDinner для Нэнси и RavenDB, который был недавно рассмотрен Айенде здесь http://ayende.com/blog/156609/reviewing-dinner-party-ndash-nerd-dinner-ported-to-ravendb-on-ravenhq?key=0c283ada-e5e8-4b7c-b76b-e9d27bfc0bf9

Я полагаю, что он использует сеансы для каждого запроса, потому что я помню, как можно было использовать пользовательский построитель модулей. Взгляните на загрузчик и RavenAwareModuleBuilder.

person TheCodeJunkie    schedule 28.06.2012
comment
Я смотрю на DinnerParty прямо сейчас. Сразу не увидит. Вы помните, где он управлял сессиями? - person Byron Sommardahl; 29.06.2012