Comment puis-je mettre en œuvre un modèle de session par demande robuste dans mon projet, tout en se concentrant sur dissimulation de l'information?

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

Question

Je suis en train de construire un projet ASP.NET MVC, avec NHibernate comme couche de persistence.

Pour l'instant, certaines fonctionnalités ont été mises en œuvre, mais utilisez uniquement des sessions NHibernate locales:. Chaque méthode qui a accédé à la base de données (lecture ou écriture) doit instancier sa propre session NHibernate, avec le « en utilisant () » clause

Le problème est que je veux tirer parti des capacités de chargement paresseux de NHibernate pour améliorer les performances de mon projet.

Cela implique une session NHibernate ouverte par demande jusqu'à ce que la vue ne soit rendue. En outre, des demandes simultanées doivent être prises en charge (sessions multiples dans le même temps).

Comment puis-je obtenir que le plus proprement possible?

Je cherchai le web un peu et appris sur le modèle de session par demande. La plupart des mises en œuvre, j'ai vu utilisé une sorte d'objet Http * (HttpContext, etc.) pour enregistrer la session. En outre, en utilisant les fonctions Application_BeginRequest / Application_EndRequest est compliquée, car ils sont congédiés pour chaque requête HTTP (fichiers ASPX, fichiers CSS, fichiers js, etc.), quand je veux seulement instancier une session une fois par demande.

Le problème que j'ai est que je ne veux pas mon point de vue ou les contrôleurs d'avoir accès à des sessions NHibernate (ou, plus généralement, et le code namespaces NHibernate). Cela signifie que je ne veux pas gérer des sessions au niveau du contrôleur, ni le point de vue d'un.

J'ai quelques options à l'esprit. Lequel semble le meilleur?

  • Utilisez des intercepteurs (comme dans GRAILS) qui se déclenchent avant et après l'action du contrôleur. Ceux-ci et d'ouvrir des sessions / transactions à proximité. Est-ce possible dans le monde ASP.NET MVC?
  • Utilisez le CurrentSessionContext Singleton fourni par NHibernate dans un contexte Web. En utilisant cette page à titre d'exemple, je pense ce qui est très prometteur, mais qui nécessite encore des filtres au niveau du contrôleur.
  • Utilisez les HttpContext.Current.Items pour stocker la session de demande. Ceci, couplé avec quelques lignes de code à Global.asax.cs, peut facilement me fournir une session sur le niveau de la demande. Cependant, cela signifie que les dépendances seront injectés entre NHibernate et mon point de vue (HttpContext).

Merci beaucoup!

Était-ce utile?

La solution

gars Eh bien, après le travail de quelques jours, je me suis finalement décidé d'utiliser les HttpContext.Current.Items pour charger la session.

Il fonctionne très bien!

Voici comment je l'ai fait

import System.Web
class SessionManager {
    public static ISession GetSession()
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session == null) {
            session = ...; // Create session, like SessionFactory.createSession()...
            HttpContext.Current.Items.Add("NHibernateSession", session);
        }
        return session;
    }

    public static void CloseSession()
    {
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session != null) {
            if (session.IsOpen) {
                session.close();
            }
            HttpContext.Current.Items.Remove("NHibernateSession");
        }
    }
}

En utilisant les méthodes statiques fournies par cette classe, on peut obtenir une session (par exemple, dans un contrôleur) qui est lié à la HttpContext actuelle (la demande Web en cours). Nous avons besoin d'un autre bout de code pour appeler la méthode FermeSession () lorsque la demande est terminée.

En Global.asax.cs:

protected void Application_EndRequest(object sender, EventArgs args)
{
    NHibernateSessionManager.CloseSession();
}

L'événement Application_EndRequest est appelée automatiquement lorsque la session est terminée, de sorte que la session peut être correctement fermée une élimination. Ceci est utile, parce que nous aurions autrement le faire dans chaque contrôleur!

Autres conseils

Utilisation DI avec un CIO. La plupart viennent avec IoC de comportement d'instanciation par demande.

Ma « solution » consiste à utiliser l'unité pour injecter la session par demande dans les contrôleurs:

http://letsfollowtheyellowbrickroad.blogspot.com /2010/05/nhibernate-sessions-in-aspnet-mvc.html

Jetez un oeil à S # arp architecture . Il est une architecture très agréable pour ASP.NET MVC et NHibernate.

Vous pouvez ajouter un filtre d'action qui permet de gérer votre session NHibernate et transactions. (Cela peut être fait à l'action ou le niveau de commande.) Voici un exemple de celui-ci:

http://weblogs.asp.net/srkirkland/archive/2009/09/03/asp-net-mvc-transaction-attribute-using-nhibernate.aspx

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