шаблон рекомендаций для использования для обработки сеансов для веб-запросов в MVC с использованием NHibernate

StackOverflow https://stackoverflow.com//questions/10693344

Вопрос

Например.Моя фабрика сеансов находится в классе MyDomain.SessionProvider.Сессия может быть открытой using ISession session = SessionProvider.Instance.OpenSession()

Шаг:Сеанспровидер.cs

public static SessionProvider Instance { get; private set; }
        private static ISessionFactory _SessionFactory;

        static SessionProvider()
        {
            var provider = new SessionProvider();
            provider.Initialize();
            Instance = provider;
        }

        private SessionProvider()
        {

        }

        private void Initialize()
        {
            string csStringName = "ConnectionString";
            var cfg = Fluently.Configure()
               //ommiting mapping and db conf.

                .ExposeConfiguration(c => c.SetProperty("current_session_context_class", "web"))
                .BuildConfiguration();
            _SessionFactory = cfg.BuildSessionFactory();

        }

        public ISession OpenSession()
        {
            return _SessionFactory.OpenSession();
        }

        public ISession GetCurrentSession()
        {
            return _SessionFactory.GetCurrentSession();
        }

Шаг:Global.asax.cs

public static ISessionFactory SessionFactory { get; private set; }

Запуск приложения

SessionFactory = SessionProvider.Instance.OpenSession().SessionFactory;

App_BeginRequest

var session = SessionFactory.OpenSession();
CurrentSessionContext.Bind(session);   

Endrequest расположить сеанс

var session = CurrentSessionContext.Unbind(SessionFactory);
session.Dispose();

Шаг 3. HomeControllerЯ должен использовать текущий сеанс, например

var session = SessionProvider.Instance.GetCurrentSession();
using (var tran = session.BeginTransaction())
{
   //retrieve data from session
}

Теперь, пытаясь получить данные на моем контроллере, например desc.в Шаге3.Я получил сообщение об ошибке, что мой сеанс закрыт.Я попытался удалить блок Application_EndRequest внутри global.asax, потому что моя транзакция была обернута сеансом, но безуспешно.Все та же ошибка.

Второй/побочный вопрос:широко ли принят этот шаблон, или его лучше обернуть внутри пользовательских атрибутов контроллеров MVC.Спасибо.

Обновлено:На моем контроллере при попытке создать текущий сеанс в строке

var session = SessionProvider.Instance.GetCurrentSession();

Я получаю следующую ошибку:

**Connection = 'session.Connection' threw an exception of type 'NHibernate.HibernateException'**

**base {System.ApplicationException} = {"Session is closed"}**
Это было полезно?

Решение

Спасибо @LeftyX

Я решил эту проблему с помощью видео TekPub Mastering NHibernate с некоторыми настройками.

Global.asax

//Whenever the request from page comes in (single request for a page)
//open session and on request end close the session.

public static ISessionFactory SessionFactory =
   MyDomain.SessionProvider.CreateSessionFactory();

public MvcApplication() 
{
    this.BeginRequest += new EventHandler(MvcApplication_BeginRequest);
    this.EndRequest +=new EventHandler(MvcApplication_EndRequest);
}

private void MvcApplication_EndRequest(object sender, EventArgs e)
{
    CurrentSessionContext.Unbind(SessionFactory).Dispose();
}

private void MvcApplication_BeginRequest(object sender, EventArgs e)
{
    CurrentSessionContext.Bind(SessionFactory.OpenSession());
}

protected void Application_Start()
{
    SessionFactory.OpenSession();
}

и внутри моего контроллера

 var session = MvcApplication.SessionFactory.GetCurrentSession();
 {
     using (ITransaction tx = session.BeginTransaction())
      {... omitting retrieving data}
 }

Другие советы

Вы можете найти пару простых и легких реализаций. здесь и здесь и найди какой-нибудь код здесь.
Мне нравится подход Ayende: все просто и понятно:

public class Global: System.Web.HttpApplication
{
    public static ISessionFactory SessionFactory = CreateSessionFactory();

    protected static ISessionFactory CreateSessionFactory()
    {
        return new Configuration()
            .Configure(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "hibernate.cfg.xml"))
            .BuildSessionFactory();
    }

    public static ISession CurrentSession
    {
        get{ return (ISession)HttpContext.Current.Items["current.session"]; }
        set { HttpContext.Current.Items["current.session"] = value; }
    }

    protected void Global()
    {
        BeginRequest += delegate
        {
            CurrentSession = SessionFactory.OpenSession();
        };
        EndRequest += delegate
        {
            if(CurrentSession != null)
                CurrentSession.Dispose();
        };
    }
}

В своих проектах я решил использовать IoC-контейнер (StructureMap).
Если вам интересно, вы можете посмотреть здесь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top