Modèle de recommandation à utiliser pour la manipulation des sessions par demande Web en MVC en utilisant NHibernate
-
12-12-2019 - |
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()
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();
}
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();
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"}**
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 .