Modèle de recommandation à utiliser pour la manipulation des sessions par demande Web en MVC en utilisant NHibernate

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

Question

Par exemple. Mon usine de session est située dans Mydomain.SessionsProvider classe. La session peut être ouverte using ISession session = SessionProvider.Instance.OpenSession()

Étape: sessionProvider.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();
        }

Étape: global.asax.cs

public static ISessionFactory SessionFactory { get; private set; }

Application Démarrer

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

App_beginrequest

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

Endrequest Disposer la session

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

étape3.homecontroller Je devrais utiliser la session actuelle comme

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

Maintenant, avec essayer de récupérer des données sur mon contrôleur comme Desc. à l'étape3. J'ai eu un message d'erreur que ma session est fermée. J'ai essayé de supprimer le bloc Application_entreQuest à l'intérieur global.aSax car ma transaction est enveloppée de session mais sans succès. Toujours la même erreur.

Seconde / Side Question: Ce modèle est-il accepté largement, ou il est préférable d'envelopper des attributs personnalisés sur des contrôleurs MVC. Merci.

mise à jour: Sur mon contrôleur lorsque vous essayez d'instancier la session actuelle en ligne

var session = SessionProvider.Instance.GetCurrentSession();

Je reçois l'erreur suivante:

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

**base {System.ApplicationException} = {"Session is closed"}**

Était-ce utile?

La solution

merci @leftyx

J'ai résolu ce problème à l'aide de Tekpub Vidéo Mastering Nibernate avec certaines personnalisations.

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();
}

et à l'intérieur de mon contrôleur

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

Autres conseils

Vous pouvez trouver quelques implémentations simples et simples ici et ici et trouverQuelque code ici .
J'aime l'approche de Ayende pour garder tout simple et propre:

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();
        };
    }
}

Dans mes projets, j'ai décidé d'utiliser un conteneur de COI (StructureMap).
Au cas où vous êtes intéressé, vous pouvez avoir un look Ici .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top